Skip to content

Fix: fall back to English for untranslated i18n keys - #342

Merged
romanetar merged 5 commits into
mainfrom
fix/i18n-fallback-to-english
Sep 11, 2026
Merged

Fix: fall back to English for untranslated i18n keys#342
romanetar merged 5 commits into
mainfrom
fix/i18n-fallback-to-english

Conversation

@romanetar

Copy link
Copy Markdown
Contributor

ref https://app.clickup.com/t/9014802374/86bbz26dk

Non english bundles are partial: zh.json and es.json only cover errors/general, while en.json has 18 sections. Since i18n-react renders the raw key when a lookup misses, components such as SponsorOrderGrid showed literal strings like "sponsor_order_grid.code" to any user whose browser language is zh or es.

Deep merge the language bundle on top of English so missing keys fall back instead of leaking the key, and default to English for unsupported languages, which previously left the text table undefined and broke every translation.

Drop the try/catch around setTexts: it never fired, as i18n-react's setTexts only assigns, so its English fallback was dead code.

Non english bundles are partial: zh.json and es.json only cover
errors/general, while en.json has 18 sections. Since i18n-react renders
the raw key when a lookup misses, components such as SponsorOrderGrid
showed literal strings like "sponsor_order_grid.code" to any user whose
browser language is zh or es.

Deep merge the language bundle on top of English so missing keys fall
back instead of leaking the key, and default to English for unsupported
languages, which previously left the text table undefined and broke every
translation.

Drop the try/catch around setTexts: it never fired, as i18n-react's
setTexts only assigns, so its English fallback was dead code.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: fc2b84d0-da30-4458-841b-4813b2bca5c4


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

romanetar and others added 3 commits September 11, 2026 10:40
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@JpMaxMan JpMaxMan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. Both bug claims check out: setTexts is a bare assignment in i18n-react, so the old try/catch really was dead code, and an unsupported language left the text table undefined and rendered every key raw — that's the larger share of the broken population, and this fixes it.

The part I want to call out explicitly, because I think it's the real value here beyond the reported bug: this makes partial translation a viable strategy instead of an all-or-nothing project.

Today, adding a key to zh.json is a liability — you either translate a section completely or users see raw keys, so nobody touches it and the bundles have sat at 12% coverage (18 of 149 keys) since they were added. After this, translating ten strings and shipping them is a safe, valid contribution; everything else renders English.

That matters more now than it used to. We can use AI to populate these bundles quickly — the hard part was never generating the strings, it's that translated UI has all sorts of unintended consequences: CJK strings blowing out fixed-width buttons, German compounds wrapping a table header into three lines, truncation in grid cells, layouts that only break at one breakpoint. You want to translate a section, look at it, fix what broke, then move to the next one. An all-or-nothing bundle forces you to absorb every one of those problems at once, in production, which is exactly why we never start. Incremental + English fallback lets us fill and test section by section.

Two follow-ups I'd want before we actually start filling the bundles in earnest (not blockers for this PR):

  1. Locale selection should belong to the consuming app. The lib reads navigator.language at import time (src/i18n/i18n.js:19). Under the incremental strategy, every key added to zh.json automatically starts appearing in summit-admin and sponsor-services for any zh-browser user — English-only products that never opted into Chinese. Right now that's only 3 visible strings in summit-admin (its own bundle wins the merge for the rest) and 10 in sponsor-services, so it's cosmetic today. But it scales directly with translation progress: the better the bundles get, the more foreign strings leak into apps that didn't ask for them. A setAppTexts(texts, { language }) signature would fix that, and gives us the switch we'd need for testing a locale on purpose.

  2. Most consumers don't go through this path at all. Only summit-admin and sponsor-services call setAppTexts. Everyone else calls T.setTexts(ownBundle) directly, which replaces i18n-react's single global table and wipes the lib defaults — CFP is missing 129 of the lib's 149 keys, track-chairs 132, event-site and summit-registration-lite all 149. Any uicore component they render using those keys shows raw keys in English browsers too. Same class of bug as the SponsorOrderGrid report, just not the instance that got filed — worth a ticket.

Worth noting for context that call-for-presentations already ships a nearly complete zh.json of its own (17 of 18 sections), so there's precedent for a real Chinese UI in the platform; it just doesn't route through the lib's bundle.

@romanetar
romanetar merged commit ca0322b into main Sep 11, 2026
5 checks passed
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.

2 participants