Internationalization
Add multi-language support to your documentation site
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:
pnpm translateThe 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:
# 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:
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:
- Add a new key to the
translationsobject with the language code - Add translations for UI elements like
displayNameandsearch - 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 # SpanishFumadocs 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.