- Extract a shared normalizeToSupportedLocale helper in @fusion/i18n used by
both the CLI env detection and the dashboard navigator detection
(convertDetectedLanguage), fixing multi-subtag navigator tags (zh-Hans-CN)
and unifying Chinese script resolution.
- Add a cross-tab storage listener to useLanguage so a language change in one
tab propagates to others.
- Dedup the namespace lists into packages/i18n/namespaces.json, consumed by
config.ts and all three build scripts (no more 3-way drift risk).
- Add tests: dashboard i18n/index.ts (document.lang mirror, init non-blocking),
useLanguage concurrent-hydration race + cross-tab adoption,
normalizeToSupportedLocale, namespace-source consistency.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add /* global */ directives to the i18n node scripts (matching the existing
prepare-publish-manifest.mjs convention) and flip the plan status to completed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Initialize the browser i18next instance with lazy per-locale catalog loading,
localStorage->navigator->htmlTag detection, script-aware zh fallback, and the
shared @fusion/i18n config. Catalogs are synced from @fusion/i18n into a
gitignored app/locales/ (predev/prebuild) and imported app-relative so Vite
emits one chunk per locale/namespace (verified: 15 chunks, none inlined into
the main bundle). First paint is gated on i18nReady to avoid raw-key flashes;
<I18nextProvider> wraps the App provider stack; vendor-i18n manualChunk added.
A build-assertion script (verify:locale-chunks) guards the KTD3a splitting
invariant. Fallback/namespace behavior is covered by @fusion/i18n config tests;
the live instance is verified via the build assertion rather than a unit test
(the dynamic catalog backend is impractical to exercise in vitest).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>