fix(i18n): add 70 keys that existed only as inline tr() fallbacks#183
Merged
Conversation
User-reported runtime warnings (`[i18n] missing key "fs_verify"`, etc.):
these keys were referenced at call sites via `tr("key", …, "English
fallback")` but never added to `en.ts`. Consequence: they rendered the
English fallback for EVERY user, including non-English locales — permanently
untranslatable, because the i18n coverage gate only checks translations OF
en.ts keys and can't see a key that isn't in en.ts at all.
Found all 70 by a multi-line-aware scan of every `tr("…")` call site across
`client/src` and diffing against en.ts (the reported 7 were just the screens
that happened to render; the real set is 70, many in multi-line `tr()` calls
the naive scan missed). Added each to en.ts with its exact call-site English,
converting `${…}` template fallbacks to the `{var}` placeholders the call
site's vars object supplies ({n}/{name}/{path}/{query}/{id}/{kind}/{time}),
then allowlisted all 70 across the 17 non-English locales (the established
new-key flow — English renders everywhere via the value; translations land
later).
Verified: a post-change scan finds ZERO used-but-missing keys; the 7
originally reported are all present; i18n coverage gate green (18 langs);
typecheck + lint + 779 tests pass. (The DEV-only runtime warning can't fire
for these anymore — the check is `!(key in en)`, now false for all 70.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Prevents the class of bug the previous commit fixed from recurring. The
i18n coverage gate only validated translations OF en.ts keys, so a key
referenced at a call site with an inline fallback but never added to en.ts
was invisible — it rendered English for all locales, untranslatable, and no
gate caught it (only a DEV-only runtime console.warn on screens actually
rendered).
`i18n-coverage.mjs` now scans client/src for `tr("literal", …)` keys and
fails if any aren't in en.ts, BEFORE the per-language check. Verified: green
with all keys present; removing one key from en.ts fails the gate naming
that exact key. Literal keys only (dynamic `tr(\`x.${k}\`)` skipped, as
find-orphan-i18n.mjs documents); the doc-example keys foo/x are ignored.
This runs in the same `npm run i18n:check` CI step (the client-frontend job)
and `npm run validate`, so it gates every PR with no new ritual.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes the user-reported runtime warnings (
[i18n] missing key "fs_verify","profile.username.loading","fs_crc32", …). These keys were referenced at call sites viatr("key", …, "English fallback")but never added toen.ts, so they rendered the English fallback for every user — including non-English locales — and were permanently untranslatable: the i18n coverage gate only checks translations of en.ts keys, so a key absent from en.ts is invisible to it.Scope — it was 70, not 7
The 7 in the bug report were just the screens that happened to render. A multi-line-aware scan of every
tr("…")call site acrossclient/src, diffed against en.ts, found 70 such keys (the naive single-line scan missed ~half — many are in multi-linetr()calls).What I did
en.tswith their exact call-site English.${…}template fallbacks to the{var}placeholders the call site's vars object actually supplies ({n}/{name}/{path}/{query}/{id}/{kind}/{time}) — verified against each call site.Verification
!(key in en), now false for all 70.Type of Change
🤖 Generated with Claude Code