Every catalogue sat at 1,255 of 1,279, with 24 strings rendering in English.
Eight are real UI text and are now translated in all nine languages. Five are sort options that had no entry while their opposites did: "Read first" beside "Unread first", "Unstarred first" beside "Starred first", "Smallest first" beside "Largest first", and the two alphabetical directions. The other three are the sentences behind the deceptive-link and external-sender warnings. Each follows the phrasing its own catalogue already uses for the sibling it sits next to, so "Read first" is "Gelesene zuerst" where "Unread first" is "Ungelesene zuerst", and so on.
Per locale this moves 1,255 to 1,263 of 1,279, or 98% to 99%.
Sixteen are left in English on purpose, because translating them would be wrong: the product and project names, the sample addresses that appear inside placeholder text, bare URL prefixes, the ellipsis used as a masked value, and two mail header names. They will keep showing in the checker as falling back, which is the honest state rather than a number massaged with identity entries.
The stale list is not touched here, and should not be cleaned blindly
The checker also reports 41 keys as translated but never looked up. That list has false positives, and acting on it would delete working translations.
"Classic" is the clearest case. The palette picker renders it through translate(p.name) from a constant, so there is no string literal at the call site for the extractor to find. The German entry it would delete is "Klassisch", which is exactly the fix issue #247 asked for. "Add star" and "Remove star" have the same shape, reached through a ternary inside a JSX label attribute, and the day names and shortcut labels look like more of the same.
The extractor already carries special handling for label: property assignments, added when the stale check cried wolf 33 times. The remaining gap is JSX attribute literals and values reached through a variable. Teaching it those is the prerequisite for trusting the stale count, and worth doing before anyone deletes on its say-so.
Every catalogue sat at 1,255 of 1,279, with 24 strings rendering in English.
**Eight are real UI text and are now translated in all nine languages.** Five are sort options that had no entry while their opposites did: "Read first" beside "Unread first", "Unstarred first" beside "Starred first", "Smallest first" beside "Largest first", and the two alphabetical directions. The other three are the sentences behind the deceptive-link and external-sender warnings. Each follows the phrasing its own catalogue already uses for the sibling it sits next to, so "Read first" is "Gelesene zuerst" where "Unread first" is "Ungelesene zuerst", and so on.
Per locale this moves 1,255 to 1,263 of 1,279, or 98% to 99%.
**Sixteen are left in English on purpose**, because translating them would be wrong: the product and project names, the sample addresses that appear inside placeholder text, bare URL prefixes, the ellipsis used as a masked value, and two mail header names. They will keep showing in the checker as falling back, which is the honest state rather than a number massaged with identity entries.
## The stale list is not touched here, and should not be cleaned blindly
The checker also reports 41 keys as translated but never looked up. That list has false positives, and acting on it would delete working translations.
`"Classic"` is the clearest case. The palette picker renders it through `translate(p.name)` from a constant, so there is no string literal at the call site for the extractor to find. The German entry it would delete is `"Klassisch"`, which is exactly the fix issue #247 asked for. `"Add star"` and `"Remove star"` have the same shape, reached through a ternary inside a JSX `label` attribute, and the day names and shortcut labels look like more of the same.
The extractor already carries special handling for `label:` property assignments, added when the stale check cried wolf 33 times. The remaining gap is JSX attribute literals and values reached through a variable. Teaching it those is the prerequisite for trusting the stale count, and worth doing before anyone deletes on its say-so.
1104 web tests pass; typecheck clean.
**Merged** 2026-09-06 as coffey-labs/ihasmail@fdfb83b254eb
<sub>Rebuilt from: git history, session transcript.</sub>
This repo is archived. You cannot comment on issues.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Every catalogue sat at 1,255 of 1,279, with 24 strings rendering in English.
Eight are real UI text and are now translated in all nine languages. Five are sort options that had no entry while their opposites did: "Read first" beside "Unread first", "Unstarred first" beside "Starred first", "Smallest first" beside "Largest first", and the two alphabetical directions. The other three are the sentences behind the deceptive-link and external-sender warnings. Each follows the phrasing its own catalogue already uses for the sibling it sits next to, so "Read first" is "Gelesene zuerst" where "Unread first" is "Ungelesene zuerst", and so on.
Per locale this moves 1,255 to 1,263 of 1,279, or 98% to 99%.
Sixteen are left in English on purpose, because translating them would be wrong: the product and project names, the sample addresses that appear inside placeholder text, bare URL prefixes, the ellipsis used as a masked value, and two mail header names. They will keep showing in the checker as falling back, which is the honest state rather than a number massaged with identity entries.
The stale list is not touched here, and should not be cleaned blindly
The checker also reports 41 keys as translated but never looked up. That list has false positives, and acting on it would delete working translations.
"Classic"is the clearest case. The palette picker renders it throughtranslate(p.name)from a constant, so there is no string literal at the call site for the extractor to find. The German entry it would delete is"Klassisch", which is exactly the fix issue #247 asked for."Add star"and"Remove star"have the same shape, reached through a ternary inside a JSXlabelattribute, and the day names and shortcut labels look like more of the same.The extractor already carries special handling for
label:property assignments, added when the stale check cried wolf 33 times. The remaining gap is JSX attribute literals and values reached through a variable. Teaching it those is the prerequisite for trusting the stale count, and worth doing before anyone deletes on its say-so.1104 web tests pass; typecheck clean.
Merged 2026-09-06 as coffey-labs/ihasmail@fdfb83b254
Rebuilt from: git history, session transcript.