Files
cms.fellies.org/docs/product-engineering/i18n-conventions.md

2.4 KiB

i18n Conventions

Scope

This document defines translation conventions for both apps in MVP0+.

  • Public app i18n: next-intl message namespaces and route-level usage
  • Admin app i18n: JSON dictionaries + runtime resolver/provider
  • Shared locale contract: @cms/i18n (de, en, es, fr; default en)

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 camelCase for 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: translateMessage returns provided fallback, else key.
    • Public: ensure required keys exist in locale JSON; avoid runtime missing-key states.

Adding New Translation Keys

  1. Add key/value in apps/*/src/messages/en.json.
  2. Add equivalent key in de/es/fr JSON files.
  3. Use key via translator:
    • Web: useTranslations("Namespace") or getTranslations("Namespace")
    • Admin: useAdminT() or server-side translateMessage(...)
  4. Add/adjust tests for behavior where relevant.

Translation Workflow

  1. Author English source copy first.
  2. Add keys in all supported locales in same change.
  3. Keep semantic parity across locales.
  4. Run checks:
    • bun run check
    • bun run typecheck
    • bun run test
  5. 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.
  • apps/web/src/i18n/request.ts
  • apps/web/src/i18n/routing.ts
  • apps/admin/src/i18n/server.ts
  • apps/admin/src/i18n/messages.ts
  • packages/i18n/src/index.ts