A polyfill/ponyfill for Intl.Locale tested by the official ECMAScript Conformance test suite

npm Version size

ECMA-402 Spec Compliance

This package implements Intl.Locale. See the conformance report for tested coverage and known limitations.

✅ Implemented Features

Core Properties

  • baseName - Base locale without extensions (e.g., "en-US")
  • language - Language subtag (e.g., "en")
  • script - Script subtag (e.g., "Latn")
  • region - Region subtag (e.g., "US")
  • calendar - Calendar identifier (e.g., "gregory")
  • collation - Collation identifier (e.g., "emoji")
  • hourCycle - Hour cycle (e.g., "h12", "h23")
  • numberingSystem - Numbering system (e.g., "latn")
  • numeric - Numeric collation flag
  • caseFirst - Case-first collation option

Core Methods

  • maximize() - Add likely subtags (e.g., "en" → "en-Latn-US")
  • minimize() - Remove likely subtags (e.g., "en-Latn-US" → "en")
  • toString() - Returns the complete locale string
  • getCalendars() - Returns supported calendars for the locale
  • getCollations() - Returns supported collations for the locale
  • getHourCycles() - Returns supported hour cycles for the locale
  • getNumberingSystems() - Returns supported numbering systems for the locale
  • getTimeZones() - Returns supported time zones for the locale region
  • getTextInfo() - Returns text directionality information
  • getWeekInfo() - Returns week-related information

Example Usage

Global import

import '@formatjs/intl-locale/polyfill.js'

// Create locale
const locale = new Intl.Locale('en-US')
locale.language // "en"
locale.region // "US"
locale.baseName // "en-US"

// With Unicode extensions
const localeWithExt = new Intl.Locale('en-US-u-ca-buddhist-nu-thai')
localeWithExt.calendar // "buddhist"
localeWithExt.numberingSystem // "thai"

// Maximize/minimize
const minimal = new Intl.Locale('en')
const maximized = minimal.maximize()
maximized.toString() // "en-Latn-US"

const full = new Intl.Locale('en-Latn-US')
const minimized = full.minimize()
minimized.toString() // "en"

// Get locale capabilities
locale.getCalendars() // ["gregory"]
locale.getNumberingSystems() // ["latn"]
locale.getHourCycles() // ["h12"]
locale.getTimeZones() // ["America/Adak", "America/Anchorage", ...]

// Text and week info
locale.getTextInfo() // {direction: "ltr"}
locale.getWeekInfo() // {firstDay: 7, weekend: [6, 7]}

ES Modules

import {Locale} from '@formatjs/intl-locale'

// Create locale
const locale = new Locale('en-US')
locale.language // "en"

Installation

npm i @formatjs/intl-locale

Requirements

Usage

Via polyfill-fastly.io

You can use polyfill-fastly.io URL Builder to create a polyfill script tag for Intl.Locale. For example:

<!-- Polyfill Intl.Locale & its dependencies -->
<script src="https://polyfill-fastly.io/v3/polyfill.min.js?features=Intl.Locale"></script>

Simple

import '@formatjs/intl-locale/polyfill.js'

Dynamic import + capability detection

async function polyfill() {
  // This platform already supports Intl.Locale
  if (shouldPolyfill()) {
    await import('@formatjs/intl-locale/polyfill.js')
  }
  // Alternatively, force the polyfill regardless of support
  await import('@formatjs/intl-locale/polyfill-force.js')
}

Tests

The Bazel :test262 target runs the upstream suite against a reviewed failure baseline. A green baseline check does not mean every test passed. See the conformance report; run bazel test //packages/intl-locale:test262-strict to require zero failures.

Weekday and numeric options

firstDayOfWeek accepts Unicode type identifiers such as mon. Numeric strings 0 and 7 both become sun; 1 through 6 become mon through sat. The empty Unicode numeric keyword in en-u-kn sets numeric to true.

Week info compatibility

getWeekInfo() follows the current ECMA-402 draft: {firstDay, weekend} with ISO weekday numbers (Monday = 1, Sunday = 7) and a fresh weekend array per call. Breaking change: the earlier proposal's minimalDays property is removed. Consumers that calculate local week numbers must obtain that value separately. Week data honors available rg region overrides, sd subdivision preferences when no region is explicit, and recognized fw first-day overrides.

Receiver validation

Locale getters and methods require a genuine initialized Locale instance. Objects inheriting from Locale.prototype and proxies around Locale instances throw TypeError. Failed calls do not give the receiver a Locale brand.

Object locale tags use standard string coercion, including Symbol.toPrimitive with the string hint and the ordinary valueOf fallback. Callable objects are accepted; primitive values other than strings are rejected.

The variants constructor option replaces existing variant subtags while preserving extensions. Empty, malformed, and duplicate variants throw RangeError.

Locale tags are canonicalized before constructor overrides are applied, so alias resolution uses the original language and script context.

minimize() tests reductions of the maximized locale, preserving variants and extensions. For example, und-Thai minimizes to th and zh-Hant to zh-TW.

Calendar and hour-cycle preferences honor available rg override data, then the explicit region, sd subdivision, likely region, and world fallback. An override without data falls back to the ordinary preferred region.

Locale option getters expose canonical Unicode values, consistent with the serialized tag. For example, calendar option islamicc resolves to islamic-civil.

maximize() preserves supplied components and leaves unmatched tags unchanged. It only searches likely-subtag candidates for the requested language.

getCollations() filters global candidates through the requested locale. An explicit co extension returns that value; an unmatched locale returns emoji and eor.