> ## Documentation Index
> Fetch the complete documentation index at: https://d83127a-margin.manicule.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.
> For every page in one file, fetch https://d83127a-margin.manicule.dev/docs/llms-full.txt (large).
> To search and read these docs as tools, connect the MCP server at https://d83127a-margin.manicule.dev/docs/api/mcp.
> Every agent surface: https://d83127a-margin.manicule.dev/docs/.well-known/llms-manifest.json

# Configure documentation languages (/docs/organize/languages)

<!-- agent-signals: reading_time_min: 4 · est_tokens: 1460 · updated: 2026-11-09 -->
Related: [Configure product documentation versions](/docs/organize/versions.md), [Generate an API reference from OpenAPI](/docs/organize/openapi.md)

> Organize locale roots and map translated pages to their published URLs.

Configure `navigation.languages` in `docs.json` to publish a navigation tree for each language. Keep translated pages at matching paths within their locale roots so the language switcher can open the corresponding page.

## Organize pages by locale

Give each language its own source directory. The default language can also use a directory: its source prefix is removed from published URLs, just as other locale roots are replaced by their language tags.

For example, store English and Spanish pages in separate roots beside `docs.json`:

```text
 docs.json
 en/
   index.mdx
   intro.mdx
 es/
   index.mdx
   intro.mdx
```

The English and Spanish `intro.mdx` files contain separate authored content. A locale directory does not translate pages automatically. Keep `intro` as the relative path in both directories even when the page titles differ.

## Configure language navigation

Each entry in `navigation.languages` has a `language` tag and its own navigation children, such as `groups`, `pages`, `tabs`, or `versions`. Set `directory` explicitly to identify the locale root. Page references still use source paths from the documentation root, not paths relative to `directory`.

Add this configuration to `docs.json` for the file tree above:

```json
{
  "name": "Example docs",
  "navigation": {
    "languages": [
      {
        "language": "en",
        "default": true,
        "directory": "en",
        "groups": [
          { "group": "Start", "pages": ["en/index", "en/intro"] }
        ]
      },
      {
        "language": "es",
        "directory": "es",
        "groups": [
          { "group": "Primeros pasos", "pages": ["es/index", "es/intro"] }
        ]
      }
    ]
  }
}
```

The first entry with `default: true` is the default locale. If none has that setting, the first entry is selected. Set it on exactly one entry so reordering languages does not change the default.

If `directory` is omitted, the locale root is inferred from the common directory of the entry's page references, including references nested under versions. Explicit roots avoid changing that inference when navigation changes. A non-default locale with no derivable content directory is skipped from locale serving and produces a `locale_unpartitioned` warning.

## Check locale and version URLs

The default locale has no language prefix. Other locales use the `language` tag as their first URL segment, regardless of the source directory name.

When a product version has its own directory, its version label follows the locale prefix. Configure versions inside each language's navigation entry to give each locale its own version tree. See [Configure documentation versions](/docs/organize/versions) for the release configuration.

These paths assume English is the default locale. The versioned rows assume a version labeled `v1` with a source directory of `en/v1` or `es/v1`, respectively:

| Page                           | Source file       | Published path |
| ------------------------------ | ----------------- | -------------- |
| English, unversioned           | `en/intro.mdx`    | `/intro`       |
| Spanish, unversioned           | `es/intro.mdx`    | `/es/intro`    |
| English, directory-backed `v1` | `en/v1/intro.mdx` | `/v1/intro`    |
| Spanish, directory-backed `v1` | `es/v1/intro.mdx` | `/es/v1/intro` |

Share the published path on your documentation site's origin, including any site base path. Do not copy the source directory path. A default product version stored in its own directory retains its version prefix; a default product version that spans the locale root has no version prefix.

After publishing, check both page responses with your site's base URL (including any base path):

```sh
DOCS_BASE_URL="https://docs.example.com"
curl --fail --location "$DOCS_BASE_URL/intro"
curl --fail --location "$DOCS_BASE_URL/es/intro"
```

Both requests should return the rendered page HTML. Open the same URLs in a browser and confirm each shows the intended language and its own sidebar. For a versioned setup, also open `/v1/intro` and `/es/v1/intro` rather than reversing the locale and version segments.

## Connect translated counterparts

Counterparts are matched by the page path remaining after removing locale and version prefixes. No translation-link frontmatter or component is required. In the example, `/intro` and `/es/intro` match because both have the remaining path `intro`. Renaming only the Spanish page to `introduccion.mdx` breaks that automatic match.

For versioned pages, the switcher prefers the same version label in the destination locale. If the current page belongs to the default version and that label is unavailable, matching uses the destination locale's default version. An unversioned page remains unversioned. A non-default version absent from the destination locale does not fall back to a different release's counterpart.

Counterpart links are checked against pages that actually exist. If a translated counterpart is missing, the language switcher points to the destination locale's home page. When a non-default locale has no authored home page, it uses the first landing link from that locale's navigation. Include an `index.mdx` in each root, as in the example, to provide a predictable destination.

Only existing counterparts receive `hreflang` alternates; a home-page fallback is not advertised as a translation of the current page. A locale marked `hidden: true` is omitted from the language selector and counterpart alternates.

Test the language switcher from `intro` in both directions, then repeat from a versioned page if versions are configured. Test a page with no translation too: the destination should be the locale home or navigation landing page, not a nonexistent translated URL.
