Files
ServerKit/frontend/scripts
Juan DenisandClaude Opus 5 2103bb87bd feat(i18n): translate the shared shell; seed the common vocabulary
Plan 79 §E wave 1. The shell is first because it is on every screen: a
translated page inside an English frame reads as broken, while a translated
frame around an English page reads as in-progress.

Converted: Sidebar (31 literals -> 1, the brand name, which must not be
translated), sidebarItems, CommandPalette, PageTopbar, MobileTopBar,
NotificationBell, EmptyState, ErrorState, ErrorBoundary, ConfirmDialog,
AppLoader. Ceiling 8225 -> 8132, and es.json now covers all 98 keys, so the
shell is provably bilingual rather than merely keyed.

Three shapes needed real tooling rather than a t() call, and each was found by
converting a file rather than by planning:

- Labels in data files (sidebarItems, palette docs entries) cannot call t():
  a table resolved at module load translates once, at import, and never
  follows a locale switch. They now declare `labelKey` beside `label`; the
  extractor collects the pair at its declaration site and useLabel resolves it
  at render. The ratchet understands the pairing, so converting a data file
  visibly moves the number (sidebarItems 27 -> 0).
- Sentences with an element inside them (ConfirmDialog's "Type <x> to
  confirm") go through <Trans>, which the extractor now reads. Splitting them
  into prefix/suffix keys would have been untranslatable: word order around
  the value differs by language and a split sentence cannot be reordered.
- Class components and module scope (ErrorBoundary, AppLoader) import a bare
  `t` from the i18n module. Reaching for `i18next.t` at the call site would
  have left that copy out of en.json, since the extractor matches bare calls.

The declarative-pair heuristic initially swept up `archKey: 'amd64'` next to
`arch: 'x64 (amd64)'` -- "Key" already means "identifier" in places -- so a
pair now only counts when the value looks like a dotted translation key.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 23:34:56 -04:00
..