Internationalization (i18n)
December 21, 2025 · View on GitHub
iDO supports multiple languages through react-i18next. This guide covers adding translations and managing locales.
Current Languages
- English (
en) - Source language - Chinese Simplified (
zh-CN) - Complete translation
File Structure
src/locales/
├── index.ts # Locale configuration
├── en.ts # English (source)
└── zh-CN.ts # Chinese Simplified
Adding Translations
Step 1: Add to English (Source)
// src/locales/en.ts
export const en = {
myFeature: {
title: 'My Feature',
description: 'This is my feature',
actions: {
save: 'Save',
cancel: 'Cancel',
delete: 'Delete'
},
messages: {
success: 'Saved successfully',
error: 'Failed to save'
}
}
}
Step 2: Add Corresponding Chinese
// src/locales/zh-CN.ts
export const zhCN = {
myFeature: {
title: '我的功能',
description: '这是我的功能',
actions: {
save: '保存',
cancel: '取消',
delete: '删除'
},
messages: {
success: '保存成功',
error: '保存失败'
}
}
}
Step 3: Validate
pnpm check-i18n
This command checks:
- ✅ All keys in
en.tsexist inzh-CN.ts - ✅ No extra keys in
zh-CN.ts - ✅ Structure matches exactly
Using Translations
In Components
import { useTranslation } from 'react-i18next'
function MyComponent() {
const { t } = useTranslation()
return (
<div>
<h1>{t('myFeature.title')}</h1>
<p>{t('myFeature.description')}</p>
<button>{t('myFeature.actions.save')}</button>
</div>
)
}
With Variables
// In locale file
export const en = {
greeting: 'Hello, {{name}}!',
itemCount: 'You have {{count}} items'
}
// In component
t('greeting', { name: 'Alice' })
// → "Hello, Alice!"
t('itemCount', { count: 5 })
// → "You have 5 items"
Pluralization
// In locale file
export const en = {
items: 'item',
items_plural: 'items'
}
// In component
t('items', { count: 1 }) // → "item"
t('items', { count: 5 }) // → "items"
Changing Language
In Settings
Users can change language in Settings → Language
Programmatically
import { i18n } from '@/lib/i18n'
// Change language
await i18n.changeLanguage('zh-CN')
// Get current language
const currentLang = i18n.language // 'en' or 'zh-CN'
Adding a New Language
1. Create Locale File
// src/locales/ja-JP.ts
export const jaJP = {
// Copy structure from en.ts
// Translate all values
}
2. Register in Index
// src/locales/index.ts
import { jaJP } from './ja-JP'
export const resources = {
en: { translation: en },
'zh-CN': { translation: zhCN },
'ja-JP': { translation: jaJP } // Add new language
}
3. Add to Settings
// src/components/settings/LanguageSettings.tsx
const languages = [
{ code: 'en', label: 'English' },
{ code: 'zh-CN', label: '简体中文' },
{ code: 'ja-JP', label: '日本語' } // Add new option
]
4. Validate
pnpm check-i18n
Best Practices
Key Naming
// ✅ Use hierarchical structure
{
activity: {
timeline: {
title: 'Activity Timeline',
empty: 'No activities'
}
}
}
// ❌ Avoid flat structure
{
activityTimelineTitle: 'Activity Timeline',
activityTimelineEmpty: 'No activities'
}
Keep Source Updated
Always update English (en.ts) first, then other languages.
# After updating en.ts
pnpm check-i18n
# → Shows which keys need translation in zh-CN.ts
Use Semantic Keys
// ✅ Semantic key names
{
actions: {
save: 'Save',
cancel: 'Cancel'
}
}
// ❌ Generic names
{
button1: 'Save',
button2: 'Cancel'
}
Avoid Hard-coded Strings
// ❌ Hard-coded
<button>Save</button>
// ✅ Translated
<button>{t('actions.save')}</button>
Backend i18n
Backend uses separate TOML files for LLM prompts:
backend/config/
├── prompts_en.toml # English prompts
└── prompts_zh.toml # Chinese prompts
Language is selected in config.toml:
[language]
default_language = "en" # or "zh"
Troubleshooting
Translation Not Showing
// Check console for missing key warnings
// i18next will show: "key 'myFeature.title' not found"
// Verify key path
console.log(t('myFeature.title'))
Validation Failing
# Run validation to see errors
pnpm check-i18n
# Common issues:
# - Missing key in translation
# - Extra key in translation
# - Structure mismatch (object vs string)
Language Not Persisting
Check that language setting is saved to localStorage:
// Should be handled by i18n config
// If not working, check src/lib/i18n.ts
Resources
- react-i18next docs
- i18next docs
- Project locale files:
src/locales/