Internationalization (i18n)
Starlight provides built-in support for multilingual sites, including routing, fallback content, and full right-to-left (RTL) language support.
Configure i18n
-
Tell Starlight about the languages you support by passing
locales
anddefaultLocale
to the Starlight integration:// astro.config.mjs import { defineConfig } from 'astro/config'; import starlight from '@astrojs/starlight'; export default defineConfig({ integrations: [ starlight({ title: 'My Docs', // Set English as the default language for this site. defaultLocale: 'en', locales: { // English docs in `src/content/docs/en/` en: { label: 'English', }, // Simplified Chinese docs in `src/content/docs/zh/` zh: { label: '简体中文', lang: 'zh-CN', }, // Arabic docs in `src/content/docs/ar/` ar: { label: 'العربية', dir: 'rtl', }, }, }), ], });
Your
defaultLocale
will be used for fallback content and UI labels, so choose the language you are most likely to start writing content in, or already have content for. -
Create a directory for each language in
src/content/docs/
. For example, for the configuration shown above, create the following folders:Directorysrc/
Directorycontent/
Directorydocs/
Directoryar/
- …
Directoryen/
- …
Directoryzh/
- …
-
You can now add content files in your language directories. Use the same file name to associate pages across languages and take advantage of Starlight’s full set of i18n features, including fallback content, translation notices, and more.
For example, create
ar/index.md
anden/index.md
to represent the homepage for Arabic and English respectively.
Use a root locale
You can use a “root” locale to serve a language without any i18n prefix in its path. For example, if English is your root locale, an English page path would look like /about
instead of /en/about
.
To set a root locale, use the root
key in your locales
config. If the root locale is also the default locale for your content, remove defaultLocale
or set it to 'root'
.
// astro.config.mjs
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
export default defineConfig({
integrations: [
starlight({
title: 'My Docs',
defaultLocale: 'root', // optional
locales: {
root: {
label: 'English',
lang: 'en', // lang is required for root locales
},
zh: {
label: '简体中文',
lang: 'zh-CN',
},
},
}),
],
});
When using a root
locale, keep pages for that language directly in src/content/docs/
instead of in a dedicated language folder. For example, here are the home page files for English and Chinese when using the config above:
Directorysrc/
Directorycontent/
Directorydocs/
- index.md
Directoryzh/
- index.md
Monolingual sites
By default, Starlight is a monolingual (English) site. To create a single language site in another language, set it as the root
in your locales
config:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
export default defineConfig({
integrations: [
starlight({
title: 'My Docs',
locales: {
root: {
label: '简体中文',
lang: 'zh-CN',
},
},
}),
],
});
This allows you to override Starlight’s default language without enabling other internationalization features for multi-language sites, such as the language picker.
Fallback content
Starlight expects you to create equivalent pages in all your languages. For example, if you have an en/about.md
file, create an about.md
for each other language you support. This allows Starlight to provide automatic fallback content for pages that have not yet been translated.
If a translation is not yet available for a language, Starlight will show readers the content for that page in the default language (set via defaultLocale
). For example, if you have not yet created a French version of your About page and your default language is English, visitors to /fr/about
will see the English content from /en/about
with a notice that this page has not yet been translated. This helps you add content in your default language and then progressively translate it when your translators have time.
Translate Starlight’s UI
In addition to hosting translated content files, Starlight allows you to translate the default UI strings (e.g. the “On this page” heading in the table of contents) so that your readers can experience your site entirely in the selected language.
English, French, German, Japanese, Portuguese, and Spanish translated UI strings are provided out of the box, and we welcome contributions to add more default languages.
You can provide translations for additional languages you support — or override our default labels — via the i18n
data collection.
-
Configure the
i18n
data collection insrc/content/config.ts
if it isn’t configured already:// src/content/config.ts import { defineCollection } from 'astro:content'; import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'; export const collections = { docs: defineCollection({ schema: docsSchema() }), i18n: defineCollection({ type: 'data', schema: i18nSchema() }), };
-
Create a JSON file in
src/content/i18n/
for each additional locale you want to provide UI translation strings for. For example, this would add translation files for Arabic and Simplified Chinese:Directorysrc/
Directorycontent/
Directoryi18n/
- ar.json
- zh-CN.json
-
Add translations for the keys you want to translate to the JSON files. Translate only the values, leaving the keys in English (e.g.
"search.label": "Buscar"
).These are the English defaults of the existing strings Starlight ships with:
{ "skipLink.label": "Skip to content", "search.label": "Search", "search.shortcutLabel": "(Press / to Search)", "search.cancelLabel": "Cancel", "themeSelect.accessibleLabel": "Select theme", "themeSelect.dark": "Dark", "themeSelect.light": "Light", "themeSelect.auto": "Auto", "languageSelect.accessibleLabel": "Select language", "menuButton.accessibleLabel": "Menu", "sidebarNav.accessibleLabel": "Main", "tableOfContents.onThisPage": "On this page", "tableOfContents.overview": "Overview", "i18n.untranslatedContent": "This content is not available in your language yet.", "page.editLink": "Edit page", "page.lastUpdated": "Last updated:", "page.previousLink": "Next", "page.nextLink": "Previous" }