Repository navigation
fix(i18n): restore extraction of plural strings with i18next v24+ - #964
Merged
Merged
Conversation
i18next-scanner v3 depends on `"i18next": "*"`, and our lockfile still resolved that to 21.8.10 from 2022. Published packages ship without their lockfile, so apps resolve `*` themselves and a fresh install gets the latest major. Since i18next v24 (22 November 2024) that breaks the scanner's plural handling, which this repo could not see. Resolve it to what a fresh install gets today, so tests and CI run against the same i18next that apps do. Only the scanner uses this entry: the runtime (@dhis2/d2-i18n) has its own `i18next@^10.3` entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
i18next-scanner v3 derives its plural suffixes from whichever i18next it resolves (it depends on `i18next: *`). i18next v24 removed `compatibilityJSON: 'v3'`, so the plural rule no longer exposes `.numbers`, the scanner computes no suffixes for `en`, and every i18n.t() call that passes `count` was silently left out of en.pot. Set the English suffixes to ['', '_plural'] after creating the parser, the same values scanner v3 computed before i18next v24. Other languages take their plural forms from the .po Plural-Forms header in generate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HendrikThePendric
force-pushed
the
fix/i18n-plural-extraction
branch
from
October 6, 2026 15:24
440bd49 to
72f26e2
Compare
|
kabaros
approved these changes
Oct 12, 2026
kabaros
left a comment
Collaborator
There was a problem hiding this comment.
Tested on the data-entry app - Before the fix, the plural translation resource didn't end up in the pot file. And they do afterwards.
KaiVandivier
approved these changes
Oct 12, 2026
dhis2-bot
added a commit
that referenced
this pull request
Oct 12, 2026
## [12.11.7](v12.11.6...v12.11.7) (2026-10-12) ### Bug Fixes * **i18n:** restore extraction of plural strings with i18next v24+ ([#964](#964)) ([1b60da5](1b60da5))
Contributor
|
🎉 This PR is included in version 12.11.7 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
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.



d2-app-scripts i18n extractsilently drops everyi18n.t()call that passescount. Those strings never reachen.potor Transifex, and at runtime English always shows the singular form. There is no error or warning.This is a regression
Plural extraction was fixed in July 2024 in #861 (LIBS-641) by moving to
i18next-scannerv3, verified manually at the time. It broke again without any change in this repo:i18next-scannerv3 depends on"i18next": "*"and builds its plural suffixes from the rules of whichever i18next it resolves. This only works withcompatibilityJSON: 'v3'.compatibilityJSON: 'v3'. Its plural rule is now a plainIntl.PluralRuleswith no.numbers, so the scanner computespluralSuffixes.en = []and writes no key at all for strings withcount.i18next@*after that date gets v24+ and is affected. Apps with an older lockfile entry keep working, which is why this looks intermittent.Lockfile bump
No automated test covered plural extraction (#861 only changed dependencies, and the existing extract tests mock the scanner). Even with one, it would have passed here: our
yarn.lockstill resolvedi18next@*to 21.8.10. This PR adds that test and updates the lockfile entry to 26.4.2, the version a fresh install of an app gets today, so the test runs against the same i18next that apps do. Only the scanner uses this entry; the runtime (@dhis2/d2-i18n) has its owni18next@^10.3entry.The fix
After creating the parser in
cli/src/lib/i18n/extract.js, set the English suffixes by hand:These are exactly the values scanner v3 computed for English before i18next v24, so the output is the same as before the regression:
Only
enis scanned. Other languages get their plural forms from thePlural-Formsheader of their.pofiles duringi18n generate, so they are not affected.Alternatives considered
i18next-scannerv4. It extracts plurals in the newer i18next format (_one/_other), which the runtime in apps (@dhis2/d2-i18n, on i18next 10) cannot read. Every app would need changes, plus a migration of existing plural translations. Out of scope for a regression fix.Testing
cli/src/lib/i18n/extract.test.jsruns the real scanner andi18nextToPotoni18n.t('And {{count}} other', { count: n, defaultValue_plural: 'And {{count}} others' })and checks for amsgid_pluralentry with the plural text inmsgstr[1]. With i18next 26 it fails without the fix.pluralSuffixesfield.yarn testincli: 44/44 pass on Node 22 and on Node 18 (the version CI uses).Apps affected by this need to run
i18n extractagain after upgrading, so the missing plural strings reachen.potand Transifex.🤖 Generated with Claude Code