Problem
On native (iOS/Android), the Intl polyfills only load locale data for en and es, but the app supports 9 beta locales (de, el, fr, it, ja, nl, pl, pt-BR, zh-hans). This gap affects every locale other than English and Spanish — it is not specific to Greek. Greek just surfaced it during review of Expensify/App#95655.
The hardcoded en/es data loads:
Pluralization is exercised at src/libs/Localize/index.ts:81 via new Intl.PluralRules(language).
Actual impact (narrower than a crash)
@formatjs/intl-pluralrules polyfill-force does not throw on a missing locale — its ResolveLocale falls back to the default locale, which is the first one loaded (en). So:
- No runtime crash. Non-
en/es locales silently use English plural categorization.
- Locales whose CLDR plural categories match English's
one/other are effectively unaffected: de, el (Greek is one/other), fr, it, nl, pt-BR, and ja/zh-hans (other only).
- The locale actually mis-served today is Polish (
pl), which has one / few / many / other. With English rules it can only ever resolve to one/other, so few/many plural forms in pl.ts are never selected → wrong grammatical number on native. Any future locale with non-English plural categories (e.g. Russian, Arabic, Czech) would hit the same problem.
- NumberFormat: the polyfill is only forced on devices with stale ICU / no
formatToParts (polyfillNumberFormat.ts:26); on modern devices native Intl.NumberFormat is used with full locale support. So this only bites older devices, and again only for non-en/es locales.
Suggested fix
Load the pluralrules (and numberformat) locale data for the active locale dynamically, the same way IntlStore already wires up translations, date-fns, and Intl.ListFormat data per locale — rather than hardcoding en/es. This keeps bundle size down (only load the selected locale's data) and closes the gap for all beta locales at once.
Filed at the request of roryabraham from the review thread on Expensify/App#95655.
Problem
On native (iOS/Android), the
Intlpolyfills only load locale data forenandes, but the app supports 9 beta locales (de,el,fr,it,ja,nl,pl,pt-BR,zh-hans). This gap affects every locale other than English and Spanish — it is not specific to Greek. Greek just surfaced it during review of Expensify/App#95655.The hardcoded
en/esdata loads:src/libs/IntlPolyfill/index.android.ts:15-17—Intl.PluralRulesis force-polyfilled (polyfill-force) with onlyen/esdatasrc/libs/IntlPolyfill/index.ios.ts:16-18— same for iOSsrc/libs/IntlPolyfill/polyfillNumberFormat.ts:32-34—Intl.NumberFormatpolyfill, onlyen/esdataPluralization is exercised at
src/libs/Localize/index.ts:81vianew Intl.PluralRules(language).Actual impact (narrower than a crash)
@formatjs/intl-pluralrulespolyfill-forcedoes not throw on a missing locale — itsResolveLocalefalls back to the default locale, which is the first one loaded (en). So:en/eslocales silently use English plural categorization.one/otherare effectively unaffected:de,el(Greek isone/other),fr,it,nl,pt-BR, andja/zh-hans(otheronly).pl), which hasone/few/many/other. With English rules it can only ever resolve toone/other, sofew/manyplural forms inpl.tsare never selected → wrong grammatical number on native. Any future locale with non-English plural categories (e.g. Russian, Arabic, Czech) would hit the same problem.formatToParts(polyfillNumberFormat.ts:26); on modern devices nativeIntl.NumberFormatis used with full locale support. So this only bites older devices, and again only for non-en/eslocales.Suggested fix
Load the
pluralrules(andnumberformat) locale data for the active locale dynamically, the same wayIntlStorealready wires up translations,date-fns, andIntl.ListFormatdata per locale — rather than hardcodingen/es. This keeps bundle size down (only load the selected locale's data) and closes the gap for all beta locales at once.Filed at the request of
roryabrahamfrom the review thread on Expensify/App#95655.