Skip to content

Native Intl polyfills only load en/es locale data — pluralization wrong for non-en/es locales (e.g. Polish) #96335

Description

@MelvinBot

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.

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions