Locales

Configure translated pages, locale sidebars, and root redirects so readers can browse docs in their language.

Before you begin

  • A single-locale site you want to split into languages, or a plan for which pages need translation first
  • Organize familiarity with sidebar groups and href values
  • Preview running locally when you want to confirm locale URLs, navigation, and the language switcher

Multi-locale behavior is driven by the sidebar property in docs.json, not a separate locales field. For how locale keys shape URLs, link prefixing, and the language switcher, see Locales.


Quick start

A minimal multi-locale setup needs three pieces:

  1. Locale folders: page files under docs/{locale}/ with matching paths (for example docs/en/index.mdx and docs/fr/index.mdx)
  2. Locale-keyed sidebar: replace the flat sidebar array in docs.json with an object keyed by locale code (en, fr, …)
  3. Local verification: open /en/... and /fr/... in Preview, then run docs check

The sections below cover planning, content files, sidebar configuration, and a full preview checklist.

Plan locale structure

Readers need distinct URL segments and matching files per language. Start by locking locale codes, folder layout, and what / should do.

Goal at /PatternWhere to configure
Send readers to a default localeredirect frontmatter on docs/index.mdxRedirects
Keep a language picker at /sidebar.default tree plus content at docs/index.mdxConfigure locale sidebars and Locales

Each translated page lives under a locale folder in docs/. Match the path after the locale key across languages:

FileURL
docs/en/installation.mdx/en/installation
docs/fr/installation.mdx/fr/installation
  • Pick stable locale codes up front

    Use two-letter ISO 639-1 keys (for example en, fr, de). They become URL segments and sidebar object keys.

  • Mirror page paths across locale folders

    You do not need every locale to have every page on day one, but sidebar links should point at pages that exist for that locale, or readers will hit 404s. See Locales for partial rollout details.

  • Sketch a sidebar tree per locale

    Each locale gets its own navigation labels and order. Keep href values locale-neutral (/installation, not /fr/installation), docs.page prefixes the active locale when building links. See Locales: Automatic link prefixing.

Add translated content files

  • Create a folder per locale under docs/

    Match folder names to your locale keys:

    text
    docs/
      en/
        index.mdx
        installation.mdx
      fr/
        index.mdx
        installation.mdx
  • Keep matching paths across languages

    Copy or write each page as its own .mdx or .md file. English at docs/en/installation.mdx and French at docs/fr/installation.mdx both use sidebar href /installation, the path after the locale folder must match so the same link works in every locale.

  • Write frontmatter in the target language

    Every page needs at least title and description in the locale readers will see. See Write: Frontmatter.

  • Retire single-locale files when you switch layouts

    If docs/installation.mdx used to serve /installation, relocate content into docs/en/installation.mdx (and other locales) and add redirects for old URLs if they were already published. To send / to a default locale, add redirect: /en (or your chosen locale) on docs/index.mdx.

Configure locale sidebars

Replace the flat sidebar array in docs.json with an object keyed by locale code.

  • Key sidebar trees by locale code

    Open docs.json and change sidebar from an array to an object. Each value is the same nested group structure you use for a single-language site:

    json
    {
      "sidebar": {
        "en": [
          {
            "group": "Getting Started",
            "pages": [
              { "title": "Get started", "href": "/" },
              { "title": "Installation", "href": "/installation" }
            ]
          }
        ],
        "fr": [
          {
            "group": "Commencer",
            "pages": [
              { "title": "Commencer", "href": "/" },
              { "title": "Installation", "href": "/installation" }
            ]
          }
        ]
      }
    }

    docs.page derives available locales from these keys (every key except default). There is no separate locales block to maintain.

  • Keep href values locale-neutral

    Write /installation, not /fr/installation. While a locale is active, internal navigation and in-page links are prefixed automatically so readers stay in the current language.

  • Serve locale-free root URLs with a default tree

    The default key is optional and is not treated as a locale. Use it for pages without a locale prefix, for example a language picker at /:

    json
    {
      "sidebar": {
        "default": [
          {
            "group": "Languages",
            "pages": [
              { "title": "English", "href": "/en" },
              { "title": "Français", "href": "/fr" }
            ]
          }
        ],
        "en": [],
        "fr": []
      }
    }

    When the URL has no recognized locale segment, docs.page renders sidebar.default (or an empty sidebar if default is omitted). See Locales for when each pattern fits.

  • Align each locale tree with its files

    Every href in a locale's sidebar must resolve to a page under docs/{locale}/. Use Organize for groups, nesting, tabs, and ordering within each tree.

Verify in preview

  • Open locale-prefixed URLs in preview

    Start Preview and open paths like /en/installation and /fr/installation.

  • Confirm navigation stays under the active locale

    Sidebar labels match the active locale, internal links keep the locale prefix, and nested groups expand for the active page.

  • Exercise the language switcher

    Switch between locales and confirm each lands on the expected locale root (/en, /fr, and so on).

  • Check root URL behavior

    If you use redirect: /en or a default sidebar, open / and confirm the behavior you planned.

  • Catch broken locale links before merge

    bash
    npx @docs.page/cli check

    The CLI catches broken internal links, missing files, and invalid redirect targets.

Troubleshooting

SymptomLikely causeFix
Locale page returns 404File path does not include the locale segmentStore the page at docs/{locale}/path.mdx so /fr/installation maps to docs/fr/installation.mdx
Sidebar link 404 in one locale onlyTranslated file missing for that localeAdd the matching file under docs/{locale}/ or remove the link from that locale's sidebar tree
Wrong sidebar on a locale URLsidebar is still a flat array, or locale key typoUse a locale-keyed object with ISO 639-1 keys. Match the first URL segment to a configured key
Links drop out of the current localehref includes a locale prefixUse locale-neutral paths like /installation. Let the platform add the prefix
Language switcher missingOnly one locale key configured, or page is locale-freeAdd a second locale key under sidebar, and open a URL under a configured locale
Root page shows wrong navigationNo default sidebar for locale-free URLsAdd sidebar.default, or redirect / to a default locale with redirect frontmatter
redirect: /en fails checkTarget page does not existAdd docs/en/index.mdx (or the path you redirect to) before publishing

Related

  • Locales: How locale keys, link prefixing, and the language switcher work in production.
  • Organize: Structure groups, tabs, and page links before you split them by locale.
  • Redirects: Send / or renamed URLs to a default locale or new path.
  • Preview: Reload locally to confirm locale URLs, sidebars, and the language switcher.