Welcome to the KanaDojo translation project! This guide will help you contribute translations to make the app accessible to more learners worldwide.
- Overview
- Translation Structure
- Getting Started
- Translation Workflow
- Naming Conventions
- Interpolation Variables
- Best Practices
- Tools & Scripts
- FAQ
KanaDojo uses namespace-based JSON files for translations. Each feature has its own translation file, making it easy to:
- Work independently: Multiple translators can work on different files without conflicts
- Stay organized: Related translations are grouped together
- Track changes: Git shows exactly what changed in each file
- Validate easily: Scripts ensure all keys exist across all languages
Currently, we support:
- 🇬🇧 English (en) - Reference language
- 🇪🇸 Spanish (es)
- 🇯🇵 Japanese (ja)
We're planning to add: Portuguese, French, German, Italian, Chinese, Korean, Russian, and Arabic.
All translation files are located in:
core/i18n/locales/
├── en/ # English (reference)
│ ├── common.json
│ ├── navigation.json
│ ├── kana.json
│ ├── kanji.json
│ ├── vocabulary.json
│ ├── achievements.json
│ ├── statistics.json
│ ├── settings.json
│ └── errors.json
├── es/ # Spanish
│ └── (same files)
└── ja/ # Japanese
└── (same files)
| Namespace | Description | Example Keys |
|---|---|---|
common.json |
Reusable UI elements (buttons, messages) | buttons.submit, messages.loading |
navigation.json |
Menu, breadcrumbs, footer | menu.home, footer.privacy |
kana.json |
Hiragana/Katakana learning feature | game.score, results.accuracy |
kanji.json |
Kanji learning feature | selection.byLevel, details.meaning |
vocabulary.json |
Vocabulary learning feature | categories.verbs, game.streak |
achievements.json |
Achievement system | unlocked, rarity.legendary |
statistics.json |
Progress tracking and stats | overview.totalStudyTime, charts.dailyActivity |
settings.json |
App configuration | appearance.theme, audio.volume |
errors.json |
Error messages | validation.required, network.timeout |
- Basic understanding of JSON format
- Text editor (VS Code recommended)
- Git (for contributing)
-
Clone the repository
git clone https://github.com/yourusername/kanadojo.git cd kanadojo -
Find your language folder
cd core/i18n/locales/es # For Spanish
-
Edit the JSON files
- Use any text editor
- Keep the same structure as English
- Translate only the values, not the keys
-
Validate your translations
npm run i18n:validate
-
Submit a pull request
-
Export translations to CSV
npm run i18n:export-csv
This creates CSV files in
scripts/i18n/reports/ -
Edit in Excel/Google Sheets
- Open the CSV files
- Translate the columns for your language
- Leave the
Keycolumn unchanged
-
Send the CSV files back
- Email them to the project maintainer
- Or upload them in a GitHub issue
-
We'll import them for you (Import script coming soon)
Start with the file you're most comfortable with. We recommend:
- Beginners:
common.json(buttons, simple messages) - Intermediate:
navigation.json,errors.json - Advanced: Feature-specific files (
kana.json,kanji.json)
JSON files use nested objects. For example:
{
"buttons": {
"submit": "Submit",
"cancel": "Cancel"
},
"messages": {
"loading": "Loading...",
"success": "Success!"
}
}Keys (left side): Never translate these - they're used in code Values (right side): Translate these to your language
English (en/common.json):
{
"buttons": {
"submit": "Submit",
"cancel": "Cancel"
}
}Spanish (es/common.json):
{
"buttons": {
"submit": "Enviar",
"cancel": "Cancelar"
}
}{
"botones": { ← DON'T translate keys!
"enviar": "Enviar", ← Keys must match English
"cancelar": "Cancelar"
}
}Some translations have variables in {{double braces}}:
{
"score": "Score: {{points}}",
"greeting": "Hello, {{name}}!"
}Rules:
- Keep the variable names exactly as they are:
{{points}},{{name}} - You can change the text around them
- The order can change based on your language's grammar
Examples:
English: "timeLeft": "Time left: {{seconds}} seconds"
Spanish: "timeLeft": "Tiempo restante: {{seconds}} segundos"
Japanese: "timeLeft": "残り時間:{{seconds}}秒"
If a key has pluralization (like {{count}}), consider your language's plural rules:
{
"itemCount": "{{count}} item",
"itemCount_plural": "{{count}} items"
}Some languages may need more plural forms - check next-intl documentation.
Some words change meaning based on context. Look at the key path:
{
"game": {
"pause": "Pause" ← Pause a game
},
"audio": {
"pause": "Pause" ← Pause audio playback
}
}In some languages, these might be different words!
Keys use dot notation to organize translations:
namespace.section.component.action
Examples:
common.buttons.submit→ Common namespace → Buttons section → Submit actionkana.game.nextQuestion→ Kana namespace → Game section → Next questionsettings.appearance.theme→ Settings namespace → Appearance section → Theme
- Use lowercase for folder names:
en,es,ja - Use lowercase + kebab-case for multi-word languages:
pt-br,zh-cn - JSON files must have exact names:
common.json, notCommon.json
| Variable | Description | Example |
|---|---|---|
{{count}} |
Numeric count | "You have {{count}} achievements" |
{{points}} |
Score/points | "Score: {{points}}" |
{{seconds}} |
Time in seconds | "Time left: {{seconds}}s" |
{{name}} |
User/item name | "Hello, {{name}}!" |
{{date}} |
Date/timestamp | "Earned on {{date}}" |
{{percentage}} |
Percentage value | "Accuracy: {{percentage}}%" |
{{current}} |
Current value | "Progress: {{current}}/{{total}}" |
{{total}} |
Total value | "Progress: {{current}}/{{total}}" |
-
Never translate variable names
// ✅ Correct "greeting": "Hola, {{name}}!" // ❌ Wrong "greeting": "Hola, {{nombre}}!"
-
Keep exact spacing inside braces
// ✅ Correct "score": "{{points}} points" // ❌ Wrong (extra spaces) "score": "{{ points }} points"
-
Adjust word order for your language
// English: Adjective before noun "description": "Your {{count}} correct answers" // Spanish: Adjective after noun "description": "Tus {{count}} respuestas correctas"
-
Be consistent: Use the same terms throughout the app
- Example: If you translate "submit" as "Enviar", use it everywhere
-
Match the tone: KanaDojo is educational and friendly
- Use polite, encouraging language
- Avoid overly formal or casual tone
-
Consider length: Some languages are longer than English
- Buttons should be concise
- Tooltips can be more verbose
-
Respect cultural context:
- Japanese honorifics (です/ます forms)
- Formal vs informal (Spanish tú/usted)
- Right-to-left languages (Arabic)
-
Preserve special characters
// ✅ Keep punctuation marks "loading": "Loading..." "success": "Success!" // ✅ Keep HTML entities if present "copyright": "© 2024 KanaDojo"
-
Don't add extra whitespace
// ✅ Correct "submit": "Enviar" // ❌ Wrong (trailing space) "submit": "Enviar "
-
Use UTF-8 encoding
- Saves files in UTF-8 to support all characters
- VS Code does this by default
-
Validate JSON syntax
- Use a JSON validator or
npm run i18n:validate - Common mistakes: Missing commas, unescaped quotes
- Use a JSON validator or
Check that all translation keys match across languages:
npm run i18n:validateOutput:
✅ All translations are valid!
Or if there are errors:
❌ ES: Missing 3 keys:
- kana.game.hint
- kanji.details.radical
...
Creates autocomplete for developers:
npm run i18n:generate-typesExport all translations to CSV files for easier editing:
npm run i18n:export-csvFiles are saved to: scripts/i18n/reports/*.csv
Find untranslated strings in the codebase:
npm run i18n:scan- Create a new folder:
core/i18n/locales/pt/(for Portuguese) - Copy all JSON files from
en/topt/ - Translate each file
- Add the language code to
core/i18n/config.ts - Run
npm run i18n:validate
The validation script will catch it! Run:
npm run i18n:validateFix by adding the missing key to your language file.
Initial draft: Yes, to get started quickly Final version: No, please review and improve machine translations
Machine translations often:
- Miss cultural context
- Use wrong formality levels
- Translate UI terms incorrectly
Use the most neutral/inclusive option when possible:
- Spanish: Use "todos/todas" → "todas las personas" or "todo el mundo"
- French: Use inclusive forms when appropriate
If the context requires a specific gender, match the subject.
Don't translate the typo! Instead:
- Open a GitHub issue describing the problem
- Suggest the correct English text
- Wait for the fix, then translate the corrected version
Approximate time per file:
common.json: 30-45 minutes (54 keys)navigation.json: 10-15 minutes (19 keys)kana.json: 45-60 minutes (45 keys)kanji.json: 60-75 minutes (50 keys)vocabulary.json: 60-75 minutes (53 keys)achievements.json: 25-30 minutes (23 keys)statistics.json: 40-50 minutes (33 keys)settings.json: 50-60 minutes (42 keys)errors.json: 25-30 minutes (23 keys)
Total: ~6-8 hours for all files (for experienced translators)
- Fork the repository
- Create a branch:
git checkout -b translations/spanish-updates - Make changes to JSON files
- Validate:
npm run i18n:validate - Commit:
git commit -m "feat(i18n): Update Spanish translations" - Push:
git push origin translations/spanish-updates - Create Pull Request on GitHub
All translators will be credited in:
README.mdContributors section- In-app credits page (coming soon)
- GitHub Issues: Report a problem or ask questions
- Email: dev@kanadojo.com
- Discord: Join our community (if available)
Thank you for helping make KanaDojo accessible to learners worldwide! 🌍✨