Real-World i18n Workflow Examples
These examples are meant for future contributors who want to use the “real power” of the internal locale tooling under apps/web/scripts/locales/* (and to avoid creating key drift between en.json and the other locale files).
1. Add a new UI string (recommended workflow)
- Edit
apps/web/locales/en.jsonand add the new key (keep the key prefix aligned with the page/feature). - Update the page/component code to use the key, for example:tsx
import { useTranslation } from 'react-i18next'; const { t } = useTranslation(); const title = t('pages.system.logs.entries.title'); - Run the tooling to propagate the key shape:
- Key-shape + key-set alignment:
pnpm locales:sync
- Fill missing English-identical gaps (optional if you have no translations yet):
pnpm locales:fill -- --all
- Key-shape + key-set alignment:
- Validate JSON only:
pnpm locales:validate
When en.json is your source-of-truth, the other locales can temporarily lag behind, but they should keep the same key tree.
2. Remove/rename a page (avoid stale keys)
When you delete a page/component or rename translation keys:
- Make sure
en.jsonno longer contains the removed keys. - Run cleanup to find and remove stale locale artifacts:
pnpm locales:cleanup
locales:cleanup is interactive:
- It still performs the existing “stale locale linkage” cleanup (remove locale files/config/index rows that drift).
- With the new heuristics, it also detects:
- “Unused keys in
en.json” (keys not referenced insrc/**usage patterns) - “Extra leaf keys in non-English locales” (keys that exist in
so.json,zh-cn.json, etc but not inen.json)
- “Unused keys in
For safety, it will only prune unused/extra keys if you explicitly confirm in the prompt.
3. After syncing, keep translations clean
When you run:
pnpm locales:sync
some non-English locale paths may be temporarily “copied from EN”. To keep quality high:
- run
pnpm locales:validate:quality(add--strictto fail CI if any English-identical strings remain) - then translate remaining English-identical gaps using
pnpm locales:fill(see fill.md)
4. Debug missing translations quickly
If you see a literal translation key on screen:
- verify the key path exists in
apps/web/locales/en.json - run
pnpm locales:validate:qualityto compare/sanity-check parity and English-identical strings across locales - for runtime behavior, remember:
fallbackLnguses English- missing keys degrade safely via the fallback
5. Quick sanity loop (copy/paste)
pnpm locales:sync
pnpm locales:fill -- --all
pnpm locales:validate
pnpm locales:validate:quality
pnpm locales:cleanupFor CI and pre-merge checks, use pnpm locales:ci (JSON + missing literal keys + the same parity report as locales:validate:quality). See ci.md.
6. Bulk-search translation keys in src/** (check-i18n-keys.sh)
For manual verification (e.g. after locales:cleanup or when auditing keys), run from apps/web:
./scripts/check-i18n-keys.sh "common.actions.save,pages.system.logs.title,navigation.items.monitor"- Pass a comma-separated list of full key paths (no spaces after commas unless you quote the whole argument).
- The script requires ripgrep (
rg) onPATH; it searches underapps/web/srcwith fixed-string matching. - Each key is reported as FOUND (with
rgline matches) or NOT FOUND — useful to confirm whether a key string still appears anywhere in source (including dynamiclabelKey/t()usage).
7. Non-English tone guidance (AI-assisted translation)
When you ask an AI agent (Cursor, Cloud, etc.) to improve non-English locale phrasing:
- follow the rules in
docs/ai-agents/locales.md - keep placeholders/interpolation tokens unchanged
- match meaning/tone to the English keys in
en.json