Localize App or Component
Workflow Checklist
- [ ] 1. Extract hardcoded strings
- [ ] 2. Replace with t() calls in source files
- [ ] 3. Add English translations to en/translation.json
- [ ] 4. Sync translations across languages
- [ ] 5. Machine translate [TODO] keys
- [ ] 6. Validate coverage
Step 1: Extract Hardcoded Strings
bash1bun run scripts/extract-strings.ts --pattern [PATTERN]
Step 2: Replace Strings with t() Calls
For each component:
- Add import:
import { useTranslation } from "react-i18next"; - Add hook:
const { t } = useTranslation(); - Replace strings:
t("apps.[appName].category.key") - Add
tto dependency arrays foruseMemo/useCallback
Key Structure
apps.[appName].menu.* # Menu labels
apps.[appName].dialogs.* # Dialog titles/descriptions
apps.[appName].status.* # Status messages
apps.[appName].ariaLabels.* # Accessibility labels
apps.[appName].help.* # Help items (auto-translated)
Common Patterns
tsx1// Basic 2t("apps.ipod.menu.file") 3 4// With variables 5t("apps.ipod.status.trackCount", { count: 5 }) 6 7// Conditional 8isPlaying ? t("pause") : t("play") 9 10// With symbol prefix 11`✓ ${t("apps.ipod.menu.shuffle")}`
Step 3: Add English Translations
Add to src/lib/locales/en/translation.json:
json1{ 2 "apps": { 3 "ipod": { 4 "menu": { "file": "File", "addSong": "Add Song..." }, 5 "dialogs": { "clearLibraryTitle": "Clear Library" }, 6 "status": { "shuffleOn": "Shuffle ON" } 7 } 8 } 9}
Step 4: Sync Across Languages
bash1bun run scripts/sync-translations.ts --mark-untranslated
Adds missing keys to all language files, marked with [TODO].
Step 5: Machine Translate
bash1bun run scripts/machine-translate.ts
Requires GOOGLE_GENERATIVE_AI_API_KEY env variable.
Step 6: Validate
bash1bun run scripts/find-untranslated-strings.ts
Component Guidelines
| Component | What to translate |
|---|---|
| Menu bars | All labels, items, submenus |
| Dialogs | Titles, descriptions, button labels |
| Status | showStatus() calls, toasts |
| Help items | Auto-translated via useTranslatedHelpItems |
Notes
- Emoji/symbols (♪, ✓) can stay hardcoded
- Help items use pattern:
apps.[appName].help.[key].title/description - Include
tin dependency arrays when used inuseMemo/useCallback