Split eager English i18n shell#4014
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
a0a4a9a to
24efaca
Compare
Greptile SummaryThis PR splits the monolithic
Confidence Score: 4/5Safe to merge; the shell split is well-validated by the new test and the non-English path is unchanged and fully awaited. The logic change is clean and the core non-English path is unaffected. The two concerns are both non-blocking: the fire-and-forget preload for English leaves a brief window where non-shell keys could show as missing with no automatic re-render, and the test's non-recursive directory scan may not cover panel subcomponents. Neither is a confirmed breakage given the shell is designed to cover all first-paint strings and the build evidence checks out. tests/i18n-english-shell.test.mjs — the eager-chrome file scan is non-recursive and may not cover all panel component files if any live in subdirectories. Important Files Changed
Sequence DiagramsequenceDiagram
participant App
participant initI18n
participant i18next
participant localeModules
App->>initI18n: initI18n()
initI18n->>i18next: "init({ resources: { en: shellTranslation } })"
i18next-->>initI18n: initialized (shell bundle only)
alt English detected
initI18n->>initI18n: preloadEnglishTranslation() [fire-and-forget]
initI18n-->>App: returns (shell active)
Note over App,localeModules: Components render with shell keys only
initI18n->>localeModules: import('../locales/en.json') [async]
localeModules-->>initI18n: full English dictionary
initI18n->>i18next: addResourceBundle('en', fullDict, deep, overwrite)
Note over i18next: Full English merged in, no re-render triggered
else Non-English detected
initI18n->>localeModules: "import('../locales/${lang}.json') [await]"
localeModules-->>initI18n: locale translation
initI18n->>localeModules: import('../locales/en.json') [await]
localeModules-->>initI18n: full English (for fallback)
initI18n->>i18next: changeLanguage(detectedLang)
initI18n-->>App: returns (both bundles active)
end
|
| function preloadEnglishTranslation(): void { | ||
| if (loadedLanguages.has('en')) return; | ||
| void ensureLanguageLoaded('en').catch((error) => { | ||
| console.warn('Failed to preload full English locale', error); | ||
| }); | ||
| } |
There was a problem hiding this comment.
Fire-and-forget preload leaves a stale-UI window for non-shell keys
preloadEnglishTranslation() is not awaited, so initI18n() returns while en.json is still in-flight. Any class-based component that renders between initI18n returning and the preload completing, and that calls t() with a key present in en.json but absent from en.shell.json, will receive the key name (missing translation). Since i18next.addResourceBundle does not emit a languageChanged event, there is no automatic mechanism to re-render those components once the full bundle lands — the stale value persists until the next independent re-render triggered by data or user interaction. The shell is designed to cover all first-paint strings, so this is largely mitigated by the test, but any gap in shell key coverage would be invisible at runtime.
24efaca to
f54ddb5
Compare
f54ddb5 to
621e381
Compare
621e381 to
5327c8a
Compare
5327c8a to
be835c7
Compare
Summary
en.jsonimport insrc/services/i18n.tswith an eageren.shell.jsonsubset.en.jsonlazy-loadable through the locale glob and preload it after English startup; non-English startup still loads the requested locale plus full English fallback before switching languages.Issue
Fixes #3535.
Validation
node --test tests/i18n-english-shell.test.mjspassed.node --test tests/country-brief-i18n.test.mjspassed.npm run typecheckpassed.git diff --checkpassed.npm run buildpassed.10331tests,0failures), edge function tests, markdown lint, MDX lint, pro-test bundle freshness, version sync.Bundle evidence
src/locales/en.json:135,820bytes; new eagersrc/locales/en.shell.json:48,175bytes.dist/assets/en-WYH83nI7.js(110.14 kB, gzip39.50 kB).dist/index.htmlmodulepreloadsi18n-qlunRAMb.js, noten-*.js.Country Facts) is present only indist/assets/en-WYH83nI7.js, not entry/i18n/panels chunks.Remaining risk
tests/i18n-english-shell.test.mjsor moved out of first-paint paths.