Files
agent-skills/skills/vitepress/references/advanced-i18n.md
Jason Woltje f5792c40be feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories:
- anthropics/skills: 16 (docs, design, MCP, testing)
- obra/superpowers: 14 (TDD, debugging, agents, planning)
- coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth)
- better-auth/skills: 5 (auth patterns)
- vercel-labs/agent-skills: 5 (React, design, Vercel)
- antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo)
- Plus 13 individual skills from various repos

Mosaic Stack is not limited to coding — the Orchestrator and
subagents serve coding, business, design, marketing, writing,
logistics, analysis, and more.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:27:42 -06:00

300 lines
5.2 KiB
Markdown

---
name: vitepress-internationalization
description: Setting up multi-language sites with locale configuration and RTL support
---
# Internationalization
VitePress supports multi-language sites through locale configuration.
## Directory Structure
Organize content by locale:
```
docs/
├─ en/
│ ├─ guide.md
│ └─ index.md
├─ zh/
│ ├─ guide.md
│ └─ index.md
└─ fr/
├─ guide.md
└─ index.md
```
Or with root as default language:
```
docs/
├─ guide.md # English (root)
├─ index.md
├─ zh/
│ ├─ guide.md
│ └─ index.md
└─ fr/
├─ guide.md
└─ index.md
```
## Configuration
```ts
// .vitepress/config.ts
import { defineConfig } from 'vitepress'
export default defineConfig({
locales: {
root: {
label: 'English',
lang: 'en'
},
zh: {
label: '简体中文',
lang: 'zh-CN',
link: '/zh/'
},
fr: {
label: 'Français',
lang: 'fr',
link: '/fr/'
}
}
})
```
## Locale-Specific Config
Override site config per locale:
```ts
locales: {
root: {
label: 'English',
lang: 'en',
title: 'My Docs',
description: 'Documentation site',
themeConfig: {
nav: [
{ text: 'Guide', link: '/guide/' }
],
sidebar: {
'/guide/': [
{ text: 'Introduction', link: '/guide/' }
]
}
}
},
zh: {
label: '简体中文',
lang: 'zh-CN',
link: '/zh/',
title: '我的文档',
description: '文档站点',
themeConfig: {
nav: [
{ text: '指南', link: '/zh/guide/' }
],
sidebar: {
'/zh/guide/': [
{ text: '介绍', link: '/zh/guide/' }
]
}
}
}
}
```
## Locale-Specific Properties
Each locale can override:
```ts
interface LocaleSpecificConfig {
lang?: string
dir?: string // 'ltr' or 'rtl'
title?: string
titleTemplate?: string | boolean
description?: string
head?: HeadConfig[] // Merged with existing
themeConfig?: ThemeConfig // Shallow merged
}
```
## Search i18n
### Local Search
```ts
themeConfig: {
search: {
provider: 'local',
options: {
locales: {
zh: {
translations: {
button: {
buttonText: '搜索',
buttonAriaLabel: '搜索'
},
modal: {
noResultsText: '没有结果',
resetButtonTitle: '重置搜索',
footer: {
selectText: '选择',
navigateText: '导航',
closeText: '关闭'
}
}
}
}
}
}
}
}
```
### Algolia Search
```ts
themeConfig: {
search: {
provider: 'algolia',
options: {
appId: '...',
apiKey: '...',
indexName: '...',
locales: {
zh: {
placeholder: '搜索文档',
translations: {
button: { buttonText: '搜索文档' }
}
}
}
}
}
}
```
## Separate Locale Directories
For fully separated locales without root fallback:
```
docs/
├─ en/
│ └─ index.md
├─ zh/
│ └─ index.md
└─ fr/
└─ index.md
```
Requires server redirect for `/``/en/`. Netlify example:
```
/* /en/:splat 302 Language=en
/* /zh/:splat 302 Language=zh
/* /en/:splat 302
```
## Persisting Language Choice
Set cookie on language change:
```vue
<!-- .vitepress/theme/Layout.vue -->
<script setup>
import DefaultTheme from 'vitepress/theme'
import { useData, inBrowser } from 'vitepress'
import { watchEffect } from 'vue'
const { lang } = useData()
watchEffect(() => {
if (inBrowser) {
document.cookie = `nf_lang=${lang.value}; expires=Mon, 1 Jan 2030 00:00:00 UTC; path=/`
}
})
</script>
<template>
<DefaultTheme.Layout />
</template>
```
## RTL Support (Experimental)
For right-to-left languages:
```ts
locales: {
ar: {
label: 'العربية',
lang: 'ar',
dir: 'rtl'
}
}
```
Requires PostCSS plugin like `postcss-rtlcss`:
```ts
// postcss.config.js
import rtlcss from 'postcss-rtlcss'
export default {
plugins: [
rtlcss({
ltrPrefix: ':where([dir="ltr"])',
rtlPrefix: ':where([dir="rtl"])'
})
]
}
```
## Organizing Config
Split config into separate files:
```
.vitepress/
├─ config/
│ ├─ index.ts # Main config, merges locales
│ ├─ en.ts # English config
│ ├─ zh.ts # Chinese config
│ └─ shared.ts # Shared config
```
```ts
// .vitepress/config/index.ts
import { defineConfig } from 'vitepress'
import { shared } from './shared'
import { en } from './en'
import { zh } from './zh'
export default defineConfig({
...shared,
locales: {
root: { label: 'English', ...en },
zh: { label: '简体中文', ...zh }
}
})
```
## Key Points
- Use `locales` object in config with `root` for default language
- Each locale can override title, description, and themeConfig
- `themeConfig` is shallow merged (define complete nav/sidebar per locale)
- Don't override `themeConfig.algolia` at locale level
- `dir: 'rtl'` enables RTL with PostCSS plugin
- Language switcher appears automatically in nav
<!--
Source references:
- https://vitepress.dev/guide/i18n
-->