---
title: Internationalization
description: Add multi-language support to your documentation site
type: guide
summary: Serve documentation in multiple languages with automatic translation via the Geistdocs CLI and Fumadocs routing.
prerequisites:
  - /docs/getting-started
related:
  - /docs/configuration
---

# Internationalization



Geistdocs supports internationalization (i18n) out of the box using Fumadocs' language-aware routing. You can serve documentation in multiple languages with automatic translation via the Geistdocs CLI.

## How It Works

The i18n system uses dynamic routing with a `[lang]` URL segment. The default language (English) doesn't show in URLs, while other languages get a prefix:

* `/docs/getting-started` - English (default)
* `/cn/docs/getting-started` - Chinese

Users can switch languages using the language selector in the navigation bar.

## Translating Content

Use the Geistdocs CLI to automatically translate your MDX files:

```bash
pnpm translate
```

The CLI reads your target locales from `geistdocs.tsx`. If no locales are found in the config, you'll be prompted to enter them manually.

Translations are generated using the Geistdocs platform and saved alongside your original file with the locale suffix (e.g., `introduction.cn.mdx`).

### Command Options

You can pass options directly to customize the translation behavior:

```bash
# Translate all MDX files (uses default pattern)
pnpm translate

# Translate files matching a specific glob pattern
pnpm translate --pattern "content/docs/**/*.mdx"

# Use a custom config file
pnpm translate --pattern "content/**/*.mdx" --config custom-config.tsx

# Use a custom translation API URL
pnpm translate --url "https://custom-api.example.com/translate"
```

| Option      | Description                                                                 |
| ----------- | --------------------------------------------------------------------------- |
| `--pattern` | Glob pattern to match MDX files (default: `content/docs/**/*.mdx`)          |
| `--config`  | Path to config file with translations (default: `geistdocs.tsx`)            |
| `--url`     | Custom translation API URL (can also use `GEISTDOCS_TRANSLATE_URL` env var) |

The CLI automatically excludes files that already have a locale suffix (e.g., `getting-started.cn.mdx`) to avoid translating already-translated content.

### Batch Processing

When translating multiple files, the CLI automatically batches them into groups of 10. Progress is displayed as each batch completes, and a 1-second delay is added between batches to avoid rate limiting.

## Configuration

Configure supported languages in `geistdocs.tsx`:

```typescript title="geistdocs.tsx"
export const translations = {
  en: {
    displayName: "English",
  },
  cn: {
    displayName: "中文",
    search: "搜尋文檔",
  },
};
```

The first locale in the `translations` object is treated as your default/source language and is excluded from translation targets.

### Adding a New Language

To add a new language:

1. Add a new key to the `translations` object with the language code
2. Add translations for UI elements like `displayName` and `search`
3. Run `pnpm translate --pattern "content/**/*.mdx"` to generate translated content

The language selector will automatically include your new language.

## Content Organization

Translated files are saved alongside the original with a locale suffix:

```
content/docs/
├── getting-started.mdx      # English (default)
├── getting-started.cn.mdx   # Chinese
├── getting-started.fr.mdx   # French
└── getting-started.es.mdx   # Spanish
```

Fumadocs automatically serves the correct file based on the URL path.

## Translating UI Elements

The `translations` object in `geistdocs.tsx` controls UI text like search placeholders, navigation labels, and error messages. Add translations for each language you support.

If you don't provide a translation for a specific element, it falls back to English.

## Language Detection

The language is determined by the URL path. There's no automatic detection based on browser settings - users must explicitly choose their language using the language selector.

This approach gives users full control and ensures they see the language they expect.


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)