Localization

Ship your documentation in more than one language

Add an i18n block to docs.json and the site gains a language switcher. Translations live alongside your English content, under a locale-prefixed folder.

Locales

List the locales you support and pick a default:

{
  "i18n": {
    "locales": ["en", "es"],
    "default": "en"
  }
}

The default locale serves at the bare URL (/example/...); other locales are prefixed (/es/example/...).

Translating pages

Mirror the content tree under a locale folder. A page at content/docs/example/guides/get-started/quickstart.mdx is translated at content/docs/es/example/guides/get-started/quickstart.mdx. Translate only the pages you're ready for — the rest fall back (below).

Fallback behavior

Choose what happens when a page isn't translated yet:

{
  "i18n": {
    "locales": ["en", "es"],
    "default": "en",
    "fallback": "show-default-with-banner"
  }
}
ValueBehavior
show-default-with-bannerShow the default language with a notice (the default).
redirect-to-defaultSend the reader to the default-language page. Sidebar links to untranslated pages leave the locale.
404Treat the untranslated page as missing. It stays in navigation; opening it shows the 404 page.
hideOmit it from that locale's navigation and URLs entirely.

Generated API reference pages aren't translatable, so they always show the default language with the notice, whatever the fallback mode. Links written as absolute paths (/example/guides/...) keep the reader's language automatically — no need to hand-prefix /es/ in translated files.

Translating UI strings

Built-in dictionaries ship for English and Spanish. For any other language — or bulk overrides — add a flat JSON file per locale under content/translations/:

content/translations/fr.json
{
  "search.placeholder": "Rechercher...",
  "search.noResults": "Aucun résultat",
  "nav.guides": "Guides",
  "feedback.prompt": "Cette page vous a-t-elle été utile ?"
}

Language menus name each locale natively ("Français") without configuration; localeLabels overrides the name, and i18n.translations in docs.json overrides individual strings (it wins over the file for the same key):

{
  "i18n": {
    "locales": ["en", "es"],
    "default": "en",
    "localeLabels": { "en": "English", "es": "Español" },
    "translations": {
      "es": { "search.placeholder": "Buscar..." }
    }
  }
}

fiskil validate warns about translation keys the engine doesn't know, so typos never fail silently.

Next: analytics

See how readers use your docs, and connect your own tools.