Translation Maintenance Workflow
For general documentation commands (build, deploy, screenshots, README generation), see Documentation Tools.
Overview
The documentation uses Docusaurus i18n with English as the default locale. Source documentation lives in docs/; translations are written to i18n/{locale}/docusaurus-plugin-content-docs/current/. Supported locales: en (default), fr, de, es, pt-BR.
When English Documentation Changes
- Update source files in
docs/ - Run extraction (if Docusaurus UI strings changed):
pnpm write-translations - Update glossary (if intlayer translations changed):
pnpm translate:glossary-ui - Add the Heading IDs:
pnpm heading-ids - Run AI translation:
pnpm translate(translates docs, JSON UI strings, and SVGs; use--no-svgfor docs only,--no-jsonto skip UI strings) - UI strings (if Docusaurus UI changed):
pnpm write-translationsextracts new keys; docs, JSON UI strings, and SVGs are translated by the AI scripts above - Test builds:
pnpm build(builds all locales) - Deploy: Use your deployment process (e.g.
pnpm deployfor GitHub Pages)
Adding New Languages
- Add locale to
docusaurus.config.tsin thei18n.localesarray - Add locale config in
localeConfigsobject - Update search plugin
languagearray (use appropriate language code, e.g.ptfor pt-BR) - Add locale to
translate.config.jsoninlocales.targets(for AI translation) - Run AI translation:
pnpm translate(translates docs, JSON UI strings, and SVGs) - Create UI translation files:
pnpm write-translations(generates structure); translate docs, JSON UI strings, and SVGs withpnpm translate
AI-Powered Translation
The project includes an automated translation system using the OpenRouter API that can translate documentation to French, German, Spanish, and Brazilian Portuguese with intelligent caching and glossary enforcement.
Prerequisites
-
OpenRouter API Key: Set the
OPENROUTER_API_KEYenvironment variable:export OPENROUTER_API_KEY=sk-or-v1-your-key-here -
Install Dependencies: Dependencies are in
package.json. Install with:cd documentation
pnpm install -
Configuration: The
translate.config.jsonfile contains default settings. You can customize models, locales, and paths as needed.To see a summary of all translation commands and the translate script options:
pnpm help
# or
pnpm translate:help
Basic Usage
Translate all documentation to all locales:
cd documentation
pnpm translate
Translate to a specific locale:
pnpm translate --locale fr # French
pnpm translate --locale de # German
pnpm translate --locale es # Spanish
pnpm translate --locale pt-br # Brazilian Portuguese
Translate a specific file or directory:
pnpm translate --path docs/intro.md
pnpm translate --path docs/development/
Preview without making changes (dry run):
pnpm translate --dry-run
Model Configuration
The translation system uses models configured in translate.config.json, one primary and a fallback.
| Configuration | Notes | Default Model |
|---|---|---|
| defaultModel | Main model for translations | anthropic/claude-3.5-haiku |
| fallbackModel | Fallback used if primary model fail | anthropic/claude-haiku-4.5 |
Check a list of all available models and cost associated at Openrouter.ai page
Testing the quality of the translation
To test the quality of a new model, change the defaultModel in the translate.config.json and run the translation for one file, for instance:
pnpm translate --force --path docs/intro.md --no-cache --locale pt-BR
and check the translated file in the i18n/pt-BR/docusaurus-plugin-content-docs/current/intro.md
Ignore Files
Add the files to skip during AI translation be in the .translate-ignore file (same style of .gitignore).
Example:
# Documentation files
# Keep the license in English
LICENSE.md
# Don't translate the API reference
api-reference/*
# Dashboard/table diagram - not referenced in docs
duplistatus_dash-table.svg
Glossary Management
The terminology glossary is automatically generated from intlayer dictionaries to maintain consistency between the application UI and documentation translations.
Generating the Glossary
cd documentation
pnpm translate:glossary-ui
This script:
- Runs
pnpm intlayer buildin the project root to generate dictionaries - Extracts terminology from
.intlayer/dictionary/*.jsonfiles - Generates
glossary-ui.csv - Updates the glossary table in
CONTRIBUTING-TRANSLATIONS.md(if that file exists)
When to Regenerate
- After updating intlayer translations in the application
- When adding new technical terms to the application
- Before major translation work to ensure consistency
User Glossary Overrides
glossary-user.csv lets you override or add terms without modifying the generated UI glossary. Format: en, locale, translation (one row per term per locale). Use * as the locale to apply a term to all configured locales. Entries take precedence over glossary-ui.csv.
Cache Management
The translation system uses a two-level cache (file-level and segment-level) stored in .translation-cache/cache.db to minimize API costs. This file is included in the Git repository to reduce future translation costs.
Cache Management Commands:
| Command | Description |
|---|---|
pnpm translate --clear-cache <locale> | Clear cache for specific locale |
pnpm translate --clear-cache | Clear all cache (both file and segment) |
pnpm translate --force | Force re-translation (clears file cache, keeps segment cache) |
pnpm translate --no-cache | Bypass cache entirely (force API calls, still saves new translations) |
pnpm translate:editor | Manual review, delete or edit cache entries |
Remove orphaned and stale cache
When changes are made to existing documents, cache entries may become orphaned or outdated. Use the commands to delete entries that are no longer required, reducing the size of the translation cache.
pnpm translate --force
pnpm translate:cleanup
Before running the cleanup script, ensure you have executed pnpm translate --force. This step is crucial to avoid accidentally deleting valid entries that are marked as stale.
The script automatically creates a backup in the .translation-cache folder, allowing you to recover any deleted data if necessary.
Manual review of the cache
When reviewing translations, use the web-based cache editing tool to view translations of specific terms, delete cache entries, delete entries using the available filters, or delete specific files. This allows you to retranslate only the desired texts or files.
For example, if a model has translated a term incorrectly, you can filter all entries for that term, change the model in the translate.config.json file, and retranslate only the lines containing those terms using the new model.
pnpm translate:editor
This will open a web UI to browse and edit cache manually (port 4000 or 4000+), so you can:
- Table view with filtering capabilities
- Inline editing of translated text
- Delete a single entry, translations for a specific file or filtered entries
- Prints source and translated file paths to the terminal for quick editor access

Heading IDs and Anchors
Consistent anchor links (IDs) are crucial for cross-references, table of contents, and deep linking. When content is translated, heading text changes, which would normally cause auto-generated anchor IDs to differ between languages.
## This is a Heading {#this-is-a-heading}
After updating or creating a new English source file, run this to ensure explicit IDs:
cd documentation
pnpm heading-ids # Adds {#id} to all headings without explicit IDs
Always use the generated ID when cross-refencing sections of the documentation.
SVG Translation
SVG translation is included in pnpm translate by default (runs after docs). SVG files in static/img/ whose names start with duplistatus are translated.
Skip SVG (docs only):
pnpm translate --no-svg
SVG-only (standalone script):
pnpm translate:svg
Options: --locale, --path, --dry-run, --no-cache, --force, --no-export-png. Uses .translate-ignore for exclusions.
UI Strings Translation (JSON)
Docusaurus UI strings and custom component labels are stored in JSON translation files. These are auto-generated by pnpm write-translations and then translated by the AI system.
How it works:
- Extraction:
pnpm write-translationsscans Docusaurus theme files and custom React components for translatable strings (like "Next", "Previous", "Search", button labels) and writes them toi18n/en/as JSON files. Each file corresponds to a Docusaurus plugin or theme. - Translation:
pnpm translate(with JSON support enabled) translates these JSON files to all target locales using the AI model, respecting the glossary. - Usage: Docusaurus automatically loads the appropriate locale's JSON files at runtime to display the UI in the selected language.
Key JSON files (all in i18n/{locale}/):
docusaurus-plugin-content-docs/current.json- Documentation UI strings (search, navigation, table of contents)docusaurus-theme-classic/navbar.json- Navbar itemsdocusaurus-theme-classic/footer.json- Footer itemscode.json- Code block labels (copy, collapse, expand)- Other plugin-specific JSON files
Skip JSON translation (docs only):
pnpm translate --no-json
Important: UI strings are usually stable, but if you add new custom components with translatable text, you must run pnpm write-translations to extract those new strings before running pnpm translate. Otherwise, the new strings will only appear in English for all locales.
The translate command logs all console output and API traffic to files in the .translation-cache/ directory. The logs include:
-
translate_<timestamp>.log: A comprehensive log of the output from thepnpm translatecommand. -
debug-traffic-<timestamp>.log: A log of all traffic sent to and received from the AI model.Note that API traffic is only logged when segments are sent to the API. If all segments are retrieved from the cache (for example, when using the
--forceoption, which overwrite the file cache, but not the translationst the segment cache), no API calls are made, and the log will only contain a header and a note.To force API calls and capture request/response traffic, use the
--no-cacheoption.
Workflow with AI Translation
- Update English documentation in
docs/ - Update glossary (if needed):
pnpm translate:glossary-uiandglossary-user.csv. - Update the headings IDs:
pnpm headings-ids - Run AI translation:
pnpm translate(translates docs, json and SVGs) - Verify translations in
i18n/{locale}/docusaurus-plugin-content-docs/current/(optional) - Test builds:
pnpm build - Deploy using your deployment process
Troubleshooting
"OPENROUTER_API_KEY not set"
- Export the environment variable or add to
.env.local
Translation quality issues
- Try different model in
translate.config.json - Delete entries in the cache and use another model
- Review the English document and rewrite it to make the translation clear
- Add more terms to
glossary-ui.csvor add overrides toglossary-user.csv(en, locale, translation)
Cache corruption
- Run
pnpm translate --clear-cacheto reset - Run
pnpm translate:cleanupto remove orphaned entries - Use
pnpm translate:editorto fix/delete individual cached translations without re-translating the whole document
Debugging OpenRouter traffic
- Logs are written to
.translation-cache/debug-traffic-<timestamp>.log. - Use this log to check if the translation problem is related to the script, prompts used or the model.
Translation Status Tracking
Track translation progress with:
pnpm translate:status
This generates a table showing the translation status for all documentation files. For example:
