trstctl /docs GitHub ↗

Web internationalization

The web console has a single localization boundary under web/src/i18n.

  • Runtime shell, primary navigation, and command-palette copy must use typed message keys from messages.ts through useTranslation() or formatMessage().
  • Production runtime catalogs ship for en-US and es-ES. en-XA and ar-XB are pseudo-locales for expansion and RTL tests only; they do not count as production localization coverage.
  • New user-facing source literals must be captured by web/src/i18n/extractedMessages.gen.ts, and the count must stay at or below web/src/i18n/extractedMessages.budget.json. Run npm --prefix web run i18n:extract intentionally when migrating copy, and npm --prefix web run i18n:check in CI; the check fails if the generated catalog is stale or if the unmanaged-literal budget grows.
  • Pseudo-locale tests use en-XA; RTL document-direction tests use ar-XB.
  • Locale and timezone state is in-memory or server-provided through /auth/me. Operators can switch locale from the shell header for the current browser session. Do not store locale, timezone, auth state, or tenant choice in localStorage or sessionStorage.
  • Date, number, and plural display code should use web/src/i18n/format.ts so later page migrations inherit the same explicit locale/timezone policy.

Routes and navigation

The console's task-based navigation and route table live in web/src/lib/navigation.ts, and every nav group label and item label is a typed message key resolved through the catalog — there is one label per route, and route parity is test-enforced (route_parity.test.ts). When a new surface is added it must register its route, a typed nav.item.* message, and a feature mapping together; the privacy (/privacy) and integrate (/integrate) surfaces follow exactly that pattern. See The web console for the full map of routes to screens.

Rendered live from github.com/ctlplne/trstctl — found a mistake? edit this page.