Skip to content

Install Lingui with multilingual visual parity coverage - #44

Merged
B0und merged 30 commits into
devfrom
i18n-refactor
Sep 17, 2026
Merged

B0und merged 30 commits into
devfrom
i18n-refactor

Conversation

@B0und

@B0und B0und commented Sep 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • replace typesafe-i18n completely with Lingui 6.7; remove its config, generated runtime, dependency, scripts, and all consumer references
  • migrate all 117 messages across the 15 supported locale catalogs to PO files
  • keep message IDs and achievement IDs statically typed while loading non-English catalogs on demand
  • self-host the Noto Sans family (Latin/Cyrillic/Greek, Devanagari, JP, SC) via @fontsource, replacing the Google Fonts CDN link
  • remove the per-locale html:lang() font-override blocks in favor of per-glyph fallback stacks: a scoped "App Serif" @font-face keeps the platform serif for Latin while Devanagari/CJK text deterministically uses the bundled fonts
  • add src/locales/config.ts as the single source of truth for supported locales, BCP-47 language-tag overrides, and script-font contracts; app code (via src/lingui.ts), LocaleProvider, and the E2E suites all consume it
  • type the E2E persisted-settings fixture against the app's SettingsValues store type and include e2e/ in tsconfig, so store changes fail type-check instead of drifting
  • fix the statistics-store rehydration crash: the zustand persist merge spread persisted state over the initial state, so empty or partial localStorage dropped fields like known_wiki_languages and made /stats and /achievements throw
  • add a Vitest browser-mode smoke test (src/routes.smoke.test.tsx) that enumerates routes from the app's own router, renders every route plus the not-found component, and fails on any error boundary, uncaught error, or console error; per-route content contracts are data-driven, so new pages need no test edits
  • declare Node.js 24+ because Lingui 6.7's dependency graph includes pseudolocale@3.1.0, whose engine floor is Node 24

Verification

  • pnpm run extract — 117 messages; 0 missing in all 14 translated catalogs
  • pnpm run compile, typecheck, lint, viteBuild — clean
  • pnpm exec vitest run — smoke test + WikiDisplay test pass; reverting the merge fix reproduces the reported length crash
  • pnpm exec playwright test — 16/16 passed; all 30 locale snapshots re-baselined after the font-stack change (Latin heading rendering is metric-identical; verified via vision audit that hi/jp/zh render real glyphs with no tofu, clipping, or overlap)

English UI

Home

English home interface

Settings

English settings interface

- initialize i18n per the dynamic-loading guide: top-level-await startup that
  awaits the persisted locale's catalog before first render, keyed dynamic
  import emitting one lazy messages chunk per locale, latest-request-wins
  activation, and html lang derived from the shared locale config
- replace the hand-written navigator scan with @lingui/detect-locale
  (fromNavigator + ordered navigator.languages fallback) in config.ts, which
  now also owns SOURCE_LOCALE and the zh->zh-Hans language-tag override
- move the message descriptor registry back to src/lingui.ts: the extractor
  excludes the catalog directory itself, so descriptors under src/locales/
  were never extracted (52 achievement messages existed only as obsolete #~
  entries that --clean would delete)
- restore msg() descriptors so extraction sees all 126 messages; resolve
  descriptors at call sites with t() instead of template-literal IDs
- wire pnpm extract --clean into build, add i18n:check catalog-drift script,
  drop the dead compile script (the vite plugin compiles .po on import)
- re-extract all 15 catalogs: active entries with live origins, stale
  gr/jp/se Language headers fixed, 9 newly wrapped UI strings translated
- wrap previously untranslated UI strings found by eslint-plugin-lingui
  (Close/Menu/Toggle theme/Please wait/Right Arrow/error fallback/GitHub
  link/Article Preview/Confirm action/Ludwig Ahgren alt) with translator
  comments; tune no-unlocalized-strings ignores to identifier-shaped data
- fix rehydration crash class flagged by review: persisted
  known_wiki_languages null now falls back to the default list, and the
  settings persist v1->v2 bump keeps unrelated fields via a migrate fn
@B0und
B0und changed the base branch from main to dev September 17, 2026 11:20
@B0und
B0und merged commit 565aec1 into dev Sep 17, 2026
2 checks passed
@B0und
B0und deleted the i18n-refactor branch September 17, 2026 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant