Skip to content

Regional variants

A regional variant is a sub-locale (fr-CA, en-GB, pt-BR...) laid on top of a base language (fr, en, pt) per BCP-47. It does not redefine the whole language: it carries only the strings that differ from the parent.

The key principle is parent fallback: a key missing in the variant falls back to the parent language, then to the source.

fr-CA -> fr -> source

Example: in fr-CA you override email with "courriel"; every other key inherits from fr with no duplication. The CDN serves a merged bundle (the fr base plus the fr-CA overrides).

This is a language dimension, distinct from surfaces (accessibility and device). Surfaces are content layers on a key; regional variants are full languages linked by a parent.

  • Declare the variant: add the BCP-47 tag (fr-CA) to the language catalog. The parent is derived from the tag (fr-CA has fr as its parent); there is no parent field to set. The catalog carries the is_variant and parent_code metadata (via GET /v1/languages), from which script and writing direction (RTL) inherit automatically.
  • Overlay model: translate only what differs from the parent. Everything else inherits, nothing to duplicate.
  • BCP-47 fallback chain: resolution follows variant -> parent -> source (fr-CA -> fr -> source).
  • Language names: i18n.nativeName(lng?) returns the endonym (the language's own native name, catalog-sourced, with no dependency on Intl.DisplayNames). For a name localized into the UI language, use Intl.DisplayNames(uiLocale, { type: 'language' }).

Add the BCP-47 tag to your locales (with @sonenta/astro: locales + defaultLocale; in react-i18next the variant comes from the version's CDN manifest). The fr-CA -> fr -> source resolution is automatic, in two layers: the CDN serves the variant as a merged bundle (fr-CA already includes the fr base), and the SDK's fallbackLng chain resolves fr-CA -> fr -> fallbackLng. Point fallbackLng at your source locale for the tail. No per-key code is needed.