A reader in Buenos Aires gets Spanish sentences and Argentine numbers, and nobody wrote an Argentine catalog.
That is not a special case. It is what falls out of treating the reader’s tag as two facts rather than one.
The two
Where a locale comes from is how each is negotiated, writing a locale is what fills the catalog half, and supported locales is what the kit ships for both.
| What it is | Falls back? | |
|---|---|---|
| Catalog locale | The locale whose catalog answers a lookup — the words somebody actually wrote | Yes. A regional variant gets the base language, because the base language is what is written |
| Formatting locale | The locale handed to Intl | No. The variant passes straight through |
So es-AR resolves to an es catalog and an es-AR formatter.
Why collapsing them is a bug rather than a simplification
Collapse toward the catalog and the Argentine reader gets Spanish words with Spanish-from-Spain formatting — the wrong decimal separator and the wrong date order for where they live.
Collapse toward the formatter and they get correct numbers with English words, because no es-AR catalog exists.
Neither is what anybody wants, and both are what one variable gives you.
The practical consequence: write the least specific tag that is true
es, not es-ES.
A plain es catalog serves every Spanish reader in the world, and each of them gets their own region’s formatting for free.
Writing es-ES means an Argentine reader either misses the catalog entirely or gets Spain’s formatting. You gain nothing and lose a continent.
Write a regional catalog only when the words genuinely differ — where a European and a Latin American reader would each find the other’s phrasing wrong. That is a real situation and it is rarer than people assume.
Nothing is bundled for the formatting half
The Workers runtime embeds full ICU, verified at the kit’s own compatibility date.
Never add a formatting polyfill, a formatting library, or locale data, and never move the compatibility date for the sake of it. Every locale’s number, date and currency formatting is already there.
Currency, and the mistake that hides
c.var.t.formatCurrency(1250, "EUR");The formatting locale decides the separators and the symbol placement. The currency decides the number of decimal places — and that is a property of the currency rather than a constant.
500 is $5.00 in USD and ¥500 in JPY. A division by 100 in a consumer is wrong in every zero-decimal market it reaches, and wrong silently, because the people who would report it are looking at a price a hundred times too small and assuming they misread.
Price in the reader’s currency is the long version.
Direction comes with it
c.var.locale?.direction; // "ltr" | "rtl"Set it on the document alongside the language attribute. The scaffolded front end keeps both in step for you.
Check it worked
- A regional tag resolves to the base catalog and the regional formatter
- Dates and numbers differ between two readers of the same language in different regions
- A zero-decimal currency renders with no decimal places
- The document’s direction attribute is right for a right-to-left locale