# Internationalization To use the built-in i18n features, one needs to create a directory structure as follows: ``` docs/ ├─ es/ │ ├─ foo.md ├─ fr/ │ ├─ foo.md ├─ foo.md ``` Then in `docs/.vitepress/config.ts`: ```ts import { defineConfig } from 'vitepress' export default defineConfig({ // shared properties and other top-level stuff... locales: { root: { label: 'English', lang: 'en' }, fr: { label: 'French', lang: 'fr', // optional, will be added as `lang` attribute on `html` tag link: '/fr/guide' // default /fr/ -- shows on navbar translations menu, can be external // other locale specific properties... } } }) ``` The following properties can be overridden for each locale (including root): ```ts interface LocaleSpecificConfig { lang?: string dir?: string title?: string titleTemplate?: string | boolean description?: string head?: HeadConfig[] // will be merged with existing head entries, duplicate meta tags are automatically removed themeConfig?: ThemeConfig // will be shallow merged, common stuff can be put in top-level themeConfig entry } ``` Refer [`DefaultTheme.Config`](https://github.com/vuejs/vitepress/blob/main/types/default-theme.d.ts) interface for details on customizing the placeholder texts of the default theme. Don't override `themeConfig.algolia` or `themeConfig.carbonAds` at locale-level. Refer [Algolia docs](../reference/default-theme-search#i18n) for using multilingual search. **Pro tip:** Config file can be stored at `docs/.vitepress/config/index.ts` too. It might help you organize stuff by creating a configuration file per locale and then merge and export them from `index.ts`. ## Separate directory for each locale The following is a perfectly fine structure: ``` docs/ ├─ en/ │ ├─ foo.md ├─ es/ │ ├─ foo.md ├─ fr/ ├─ foo.md ``` However, VitePress won't redirect `/` to `/en/` by default. You'll need to configure your server for that. For example, on Netlify, you can add a `docs/public/_redirects` file like this: ``` /* /es/:splat 302 Language=es /* /fr/:splat 302 Language=fr /* /en/:splat 302 ``` **Pro tip:** If using the above approach, you can use `nf_lang` cookie to persist user's language choice: ```ts // docs/.vitepress/theme/index.ts import DefaultTheme from 'vitepress/theme' import Layout from './Layout.vue' export default { extends: DefaultTheme, Layout } ``` ```vue ``` ## RTL Support (Experimental) For RTL support, specify `dir: 'rtl'` in config and use some RTLCSS PostCSS plugin like , or . You'll need to configure your PostCSS plugin to use `:where([dir="ltr"])` and `:where([dir="rtl"])` as prefixes to prevent CSS specificity issues.