Files
tolaria/docs/adr/0087-json-catalogs-and-lara-cli-localization.md
2026-04-27 13:06:59 +02:00

2.5 KiB

type, id, title, status, date, supersedes
type id title status date supersedes
ADR 0087 JSON locale catalogs with Lara CLI synchronization active 2026-04-27
0084

Context

ADR-0084 established an app-owned localization layer in src/lib/i18n.ts with English fallback and hand-maintained TypeScript dictionaries. That was enough for the first localized UI surface, but it does not scale well to a broader locale matrix or machine-assisted translation workflows.

We now want Tolaria to support a wider set of locales and to automate translation updates with Lara CLI while keeping the runtime dependency-light and preserving the existing English fallback behavior.

Decision

Tolaria will keep its app-owned runtime localization layer, but the translation source-of-truth moves to flat JSON catalogs in src/lib/locales/.

  • src/lib/locales/en.json is the canonical source catalog.
  • Additional locale files use one JSON file per locale code (for example zh-CN.json, fr-FR.json).
  • src/lib/i18n.ts keeps fallback, interpolation, locale resolution, and props-down locale wiring, but it now loads locale catalogs from JSON files instead of TypeScript objects.
  • Lara CLI configuration lives in lara.yaml, and translation runs happen through repo scripts (pnpm l10n:translate, pnpm l10n:translate:force).
  • scripts/validate-locales.mjs verifies that every locale catalog present in the repo matches the English keyset and only contains flat string values.
  • Legacy stored preferences such as zh-Hans are normalized to the canonical zh-CN locale.

Alternatives considered

  • Keep TypeScript dictionaries and point Lara at .ts files: possible, but JSON is the more standard interchange format for translation tooling and keeps diffs simpler for translators and reviewers.
  • Adopt a full frontend i18n framework now: rejected because Tolaria already has working locale propagation and fallback behavior, and the immediate need is better content management plus translation automation.
  • Store translated strings outside the app repo: rejected because Tolaria's chrome localization should stay versioned with the app code that consumes it.

Consequences

  • Translators and automation tools now work against plain JSON catalogs instead of editing source code.
  • The runtime keeps English fallback behavior, so a missing locale file or missing key does not break app chrome.
  • Locale additions become a data/config change first: add the locale metadata, run Lara, review JSON output, then ship.
  • Localization work now has a dedicated validation step that can run in CI or before commit.