2.4 KiB
2.4 KiB
i18n Conventions
Scope
This document defines translation conventions for both apps in MVP0+.
- Public app i18n:
next-intlmessage namespaces and route-level usage - Admin app i18n: JSON dictionaries + runtime resolver/provider
- Shared locale contract:
@cms/i18n(de,en,es,fr; defaulten)
Locale Policy
- Source of truth:
packages/i18n/src/index.ts - Current enabled locales are code-driven and shared across web/admin.
- Admin-managed locale toggles are planned for a later MVP.
Key Naming Conventions
- Use
camelCasefor keys. - Group by domain namespace (not by component filename).
- Keep keys stable; update values, not key names, during copy edits.
Public app namespaces
Layout.*Home.*LanguageSwitcher.*- Page-specific namespaces, e.g.
About.*,Contact.* - Metadata namespace:
Seo.*
Admin app namespaces
common.*auth.*dashboard.*settings.*
Message Structure
- Keep messages as nested JSON objects.
- Avoid very deep nesting (prefer 2-3 levels).
- Keep punctuation in translation values, not code.
- Avoid embedding HTML in message strings.
Fallback Rules
- Unknown/invalid locale values fallback to default locale
en. - Missing translation key behavior:
- Admin:
translateMessagereturns provided fallback, else key. - Public: ensure required keys exist in locale JSON; avoid runtime missing-key states.
- Admin:
Adding New Translation Keys
- Add key/value in
apps/*/src/messages/en.json. - Add equivalent key in
de/es/frJSON files. - Use key via translator:
- Web:
useTranslations("Namespace")orgetTranslations("Namespace") - Admin:
useAdminT()or server-sidetranslateMessage(...)
- Web:
- Add/adjust tests for behavior where relevant.
Translation Workflow
- Author English source copy first.
- Add keys in all supported locales in same change.
- Keep semantic parity across locales.
- Run checks:
bun run checkbun run typecheckbun run test
- For route-level i18n behavior changes, run e2e smoke:
bunx playwright test --grep "i18n smoke"
QA Checklist
- Locale switch persists after refresh.
- Page headings and navigation labels translate correctly.
- Metadata (
Seo) strings resolve per locale. - No missing-key placeholders visible in UI.
Related Files
apps/web/src/i18n/request.tsapps/web/src/i18n/routing.tsapps/admin/src/i18n/server.tsapps/admin/src/i18n/messages.tspackages/i18n/src/index.ts