Comment construire des identifiants de locale à partir de composants

Construisez des identifiants de locale en combinant les codes de langue, d'écriture et de région en JavaScript

Introduction

Les identifiants de locale comme en-US ou zh-Hans-CN encodent des informations sur la langue, le système d'écriture et la région. Parfois, vous devez construire ces identifiants de manière programmatique plutôt que d'utiliser une chaîne fixe. Par exemple, vous pourriez permettre aux utilisateurs de sélectionner leur langue et leur région séparément, puis les combiner en un identifiant de locale valide.

Le constructeur Intl.Locale de JavaScript vous permet de construire des identifiants de locale à partir de composants individuels. Vous pouvez spécifier la langue, l'écriture et la région comme paramètres séparés, et le constructeur les assemble en un identifiant correctement formaté.

Ce guide explique comment construire des identifiants de locale à partir de composants, quand utiliser cette approche et comment gérer les cas particuliers.

Comprendre les composants des identifiants de locale

Les identifiants de locale se composent de composants séparés par des traits d'union. Chaque composant représente un aspect différent des préférences culturelles.

Le code de langue spécifie quelle langue utiliser. Il utilise deux ou trois lettres minuscules de la norme ISO 639 :

  • en pour l'anglais
  • es pour l'espagnol
  • fr pour le français
  • zh pour le chinois
  • ar pour l'arabe

Le code d'écriture spécifie le système d'écriture. Il utilise quatre lettres avec la première lettre en majuscule, de la norme ISO 15924 :

  • Hans pour les caractères chinois simplifiés
  • Hant pour les caractères chinois traditionnels
  • Cyrl pour l'écriture cyrillique
  • Latn pour l'écriture latine

Le code de région spécifie la zone géographique. Il utilise deux lettres majuscules de la norme ISO 3166-1 ou trois chiffres de la norme UN M.49 :

  • US pour les États-Unis
  • GB pour le Royaume-Uni
  • CN pour la Chine
  • MX pour le Mexique

Ces composants se combinent dans un ordre spécifique : langue, puis écriture, puis région. Par exemple, zh-Hans-CN signifie langue chinoise, écriture simplifiée, région Chine.

Construire des locales avec uniquement la langue et la région

Le scénario le plus courant consiste à combiner les codes de langue et de région. La plupart des applications n'ont pas besoin de spécifier l'écriture car chaque langue possède une écriture par défaut.

Vous pouvez construire une locale en passant le code de langue comme premier argument et un objet d'options avec la région :

const locale = new Intl.Locale("en", {
  region: "US"
});

console.log(locale.toString());
// Output: "en-US"

Cela crée un identifiant de locale pour l'anglais américain.

Vous pouvez construire différentes variantes régionales de la même langue :

const usEnglish = new Intl.Locale("en", { region: "US" });
const britishEnglish = new Intl.Locale("en", { region: "GB" });
const canadianEnglish = new Intl.Locale("en", { region: "CA" });

console.log(usEnglish.toString()); // "en-US"
console.log(britishEnglish.toString()); // "en-GB"
console.log(canadianEnglish.toString()); // "en-CA"

Chaque variante utilise la même langue mais des conventions de formatage régionales différentes.

Construire des locales avec langue, écriture et région

Certaines langues nécessitent des codes d'écriture explicites. Le chinois, le serbe et quelques autres langues utilisent plusieurs systèmes d'écriture. Vous devez spécifier l'écriture pour éviter toute ambiguïté.

Vous pouvez ajouter le composant d'écriture à l'objet d'options :

const simplifiedChinese = new Intl.Locale("zh", {
  script: "Hans",
  region: "CN"
});

console.log(simplifiedChinese.toString());
// Output: "zh-Hans-CN"

Cela crée une locale pour le chinois simplifié tel qu'utilisé en Chine.

Le chinois traditionnel utilise une écriture et une région différentes :

const traditionalChinese = new Intl.Locale("zh", {
  script: "Hant",
  region: "TW"
});

console.log(traditionalChinese.toString());
// Output: "zh-Hant-TW"

Le code d'écriture distingue les deux systèmes d'écriture.

Le serbe utilise à la fois les écritures cyrillique et latine. Vous devez spécifier quelle écriture utiliser :

const serbianCyrillic = new Intl.Locale("sr", {
  script: "Cyrl",
  region: "RS"
});

const serbianLatin = new Intl.Locale("sr", {
  script: "Latn",
  region: "RS"
});

console.log(serbianCyrillic.toString()); // "sr-Cyrl-RS"
console.log(serbianLatin.toString()); // "sr-Latn-RS"

Les deux locales utilisent la langue serbe en Serbie, mais avec des systèmes d'écriture différents.

Construire des locales à partir de sélections utilisateur

Les interfaces utilisateur permettent souvent aux utilisateurs de sélectionner la langue et la région séparément. Vous pouvez combiner ces sélections en un identifiant de locale.

Considérez un formulaire de paramètres avec deux menus déroulants :

function buildLocaleFromSelections(languageCode, regionCode) {
  const locale = new Intl.Locale(languageCode, {
    region: regionCode
  });

  return locale.toString();
}

const userLocale = buildLocaleFromSelections("es", "MX");
console.log(userLocale);
// Output: "es-MX"

Cela crée un identifiant de locale à partir de sélections indépendantes.

Vous pouvez valider les sélections en interceptant les erreurs du constructeur :

function buildLocaleFromSelections(languageCode, regionCode) {
  try {
    const locale = new Intl.Locale(languageCode, {
      region: regionCode
    });
    return {
      success: true,
      locale: locale.toString()
    };
  } catch (error) {
    return {
      success: false,
      error: error.message
    };
  }
}

const valid = buildLocaleFromSelections("fr", "CA");
console.log(valid);
// Output: { success: true, locale: "fr-CA" }

const invalid = buildLocaleFromSelections("invalid", "XX");
console.log(invalid);
// Output: { success: false, error: "..." }

Le constructeur lève une RangeError si un composant est invalide.

Construire des locales avec des composants optionnels

Toutes les locales n'ont pas besoin de tous les composants. Vous pouvez omettre les composants qui ne sont pas requis.

Une locale avec uniquement la langue omets la région et l'écriture :

const locale = new Intl.Locale("fr");
console.log(locale.toString());
// Output: "fr"

Cela représente le français sans spécifier de région ou d'écriture particulière.

Vous pouvez inclure conditionnellement des composants en fonction de la saisie utilisateur :

function buildLocale(language, options = {}) {
  const localeOptions = {};

  if (options.region) {
    localeOptions.region = options.region;
  }

  if (options.script) {
    localeOptions.script = options.script;
  }

  const locale = new Intl.Locale(language, localeOptions);
  return locale.toString();
}

console.log(buildLocale("en"));
// Output: "en"

console.log(buildLocale("en", { region: "US" }));
// Output: "en-US"

console.log(buildLocale("zh", { script: "Hans", region: "CN" }));
// Output: "zh-Hans-CN"

La fonction construit l'identifiant de locale valide le plus simple en fonction des informations disponibles.

Remplacer des composants dans des locales existantes

Vous pouvez prendre un identifiant de locale existant et remplacer des composants spécifiques. Cela est utile lorsque vous devez modifier une partie tout en conservant les autres intactes.

Le deuxième argument du constructeur remplace les composants du premier argument :

const baseLocale = new Intl.Locale("en-US");
const withDifferentRegion = new Intl.Locale(baseLocale, {
  region: "GB"
});

console.log(withDifferentRegion.toString());
// Output: "en-GB"

La nouvelle locale conserve la langue mais change la région.

Vous pouvez remplacer plusieurs composants :

const original = new Intl.Locale("zh-Hans-CN");
const modified = new Intl.Locale(original, {
  script: "Hant",
  region: "TW"
});

console.log(modified.toString());
// Output: "zh-Hant-TW"

Cela modifie à la fois l'écriture et la région tout en préservant la langue.

Ajouter des préférences de formatage aux locales construites

Au-delà de la langue, de l'écriture et de la région, les locales peuvent inclure des préférences de formatage. Ces préférences contrôlent la façon dont les dates, les nombres et d'autres valeurs apparaissent.

Vous pouvez ajouter des préférences de calendrier lors de la construction d'une locale :

const locale = new Intl.Locale("ar", {
  region: "SA",
  calendar: "islamic"
});

console.log(locale.toString());
// Output: "ar-SA-u-ca-islamic"

console.log(locale.calendar);
// Output: "islamic"

La préférence de calendrier apparaît comme une extension Unicode dans la chaîne d'identifiant.

Vous pouvez spécifier plusieurs préférences de formatage :

const locale = new Intl.Locale("en", {
  region: "US",
  calendar: "gregory",
  numberingSystem: "latn",
  hourCycle: "h12"
});

console.log(locale.toString());
// Output: "en-US-u-ca-gregory-hc-h12-nu-latn"

Le constructeur ordonne les clés d'extension par ordre alphabétique.

Ces préférences affectent la façon dont les formateurs affichent les données :

const locale = new Intl.Locale("ar", {
  region: "EG",
  numberingSystem: "arab"
});

const formatter = new Intl.NumberFormat(locale);
console.log(formatter.format(12345));
// Output: "١٢٬٣٤٥" (Arabic-Indic numerals)

La préférence du système de numération contrôle quels chiffres apparaissent.

Validation des combinaisons de composants

Toutes les combinaisons de langue, script et région ne sont pas significatives. Le constructeur accepte tous les composants syntaxiquement valides, mais certaines combinaisons peuvent ne pas représenter de locales réelles.

Le constructeur valide la syntaxe mais pas l'exactitude sémantique :

// Syntactically valid but semantically questionable
const locale = new Intl.Locale("en", {
  script: "Arab",
  region: "JP"
});

console.log(locale.toString());
// Output: "en-Arab-JP"

Cela construit une locale pour l'anglais en script arabe au Japon. L'identifiant est valide selon BCP 47, mais il ne représente pas une locale du monde réel.

Vous pouvez utiliser la méthode maximize() pour vérifier si une locale correspond aux modèles courants :

const locale = new Intl.Locale("en", { region: "JP" });
const maximized = locale.maximize();

console.log(maximized.toString());
// Output: "en-Latn-JP"

La méthode ajoute le script le plus probable pour la langue. Si le résultat correspond aux modèles attendus, la combinaison est raisonnable.

Lecture des composants à partir de locales construites

Après avoir construit une locale, vous pouvez lire ses composants en tant que propriétés.

La propriété language renvoie le code de langue :

const locale = new Intl.Locale("fr", { region: "CA" });
console.log(locale.language);
// Output: "fr"

La propriété region renvoie le code de région :

const locale = new Intl.Locale("fr", { region: "CA" });
console.log(locale.region);
// Output: "CA"

La propriété script renvoie le code de script s'il est spécifié :

const locale = new Intl.Locale("zh", {
  script: "Hans",
  region: "CN"
});

console.log(locale.script);
// Output: "Hans"

Si le script n'est pas spécifié, la propriété renvoie undefined :

const locale = new Intl.Locale("en", { region: "US" });
console.log(locale.script);
// Output: undefined

La propriété baseName renvoie l'identifiant complet sans les extensions :

const locale = new Intl.Locale("ar", {
  region: "SA",
  calendar: "islamic",
  numberingSystem: "arab"
});

console.log(locale.baseName);
// Output: "ar-SA"

Cela vous donne la partie langue-script-région sans les préférences de formatage.

Conversion des identifiants de locale en chaînes de caractères

La méthode toString() renvoie l'identifiant de locale complet sous forme de chaîne de caractères :

const locale = new Intl.Locale("es", { region: "MX" });
const identifier = locale.toString();

console.log(identifier);
// Output: "es-MX"

Vous pouvez utiliser la chaîne avec d'autres API Intl :

const locale = new Intl.Locale("de", { region: "DE" });
const formatter = new Intl.NumberFormat(locale.toString());

const price = 1234.56;
console.log(formatter.format(price));
// Output: "1.234,56"

Le formateur accepte la représentation sous forme de chaîne.

La plupart des API Intl acceptent également directement les objets locale :

const locale = new Intl.Locale("de", { region: "DE" });
const formatter = new Intl.NumberFormat(locale);

L'API appelle toString() en interne si nécessaire.

Cas d'usage pratiques

La construction d'identifiants de locale à partir de composants résout plusieurs problèmes courants dans les applications internationalisées.

Création de sélecteurs de locale

Les interfaces utilisateur permettent souvent aux utilisateurs de choisir la langue et la région séparément. Vous combinez les sélections :

function createLocaleFromPicker(languageSelect, regionSelect) {
  const language = languageSelect.value;
  const region = regionSelect.value;

  const locale = new Intl.Locale(language, { region });
  return locale.toString();
}

// User selects "Spanish" and "Mexico"
const selectedLocale = createLocaleFromPicker(
  { value: "es" },
  { value: "MX" }
);

console.log(selectedLocale);
// Output: "es-MX"

Génération de variantes de locale

Vous pouvez générer plusieurs variantes régionales à partir d'un seul code de langue :

function generateRegionalVariants(languageCode, regionCodes) {
  return regionCodes.map(regionCode => {
    const locale = new Intl.Locale(languageCode, {
      region: regionCode
    });
    return locale.toString();
  });
}

const englishVariants = generateRegionalVariants("en", [
  "US",
  "GB",
  "CA",
  "AU",
  "NZ"
]);

console.log(englishVariants);
// Output: ["en-US", "en-GB", "en-CA", "en-AU", "en-NZ"]

Cela crée une liste d'identifiants de locale pour différentes régions anglophones.

Construction de locales à partir de paramètres d'URL

Les URL encodent souvent les préférences de locale sous forme de paramètres séparés. Vous pouvez construire une locale à partir de ces paramètres :

function getLocaleFromURL(url) {
  const params = new URL(url).searchParams;
  const language = params.get("lang");
  const region = params.get("region");

  if (!language) {
    return null;
  }

  const options = {};
  if (region) {
    options.region = region;
  }

  try {
    const locale = new Intl.Locale(language, options);
    return locale.toString();
  } catch (error) {
    return null;
  }
}

const locale1 = getLocaleFromURL("https://example.com?lang=fr&region=CA");
console.log(locale1);
// Output: "fr-CA"

const locale2 = getLocaleFromURL("https://example.com?lang=ja");
console.log(locale2);
// Output: "ja"

Normalisation des identifiants de locale

Vous pouvez normaliser les identifiants de locale en les analysant et en les reconstruisant :

function normalizeLocale(identifier) {
  try {
    const locale = new Intl.Locale(identifier);
    return locale.toString();
  } catch (error) {
    return null;
  }
}

console.log(normalizeLocale("EN-us"));
// Output: "en-US"

console.log(normalizeLocale("zh_Hans_CN"));
// Output: null (invalid separator)

Le constructeur normalise la casse et valide la structure.

Configuration des formateurs avec les préférences utilisateur

Vous pouvez construire des identifiants de locale avec des préférences de formatage basées sur les paramètres utilisateur :

function buildFormatterLocale(language, region, preferences) {
  const locale = new Intl.Locale(language, {
    region,
    hourCycle: preferences.use24Hour ? "h23" : "h12",
    numberingSystem: preferences.numberingSystem
  });

  return locale;
}

const userPreferences = {
  use24Hour: true,
  numberingSystem: "latn"
};

const locale = buildFormatterLocale("fr", "FR", userPreferences);

const timeFormatter = new Intl.DateTimeFormat(locale, {
  hour: "numeric",
  minute: "numeric"
});

const now = new Date("2025-10-15T14:30:00");
console.log(timeFormatter.format(now));
// Output: "14:30" (24-hour format)

La locale inclut les préférences de formatage issues des paramètres utilisateur.

Quand construire des locales à partir de composants

Construire des locales à partir de composants est utile dans des scénarios spécifiques. Utilisez cette approche lorsque vous disposez de données de langue et de région séparées, lors du traitement de saisies utilisateur, ou lors de la génération programmatique de variantes de locale.

Utilisez une chaîne littérale pour les locales fixes :

// Good for fixed locales
const locale = new Intl.Locale("en-US");

Construisez à partir de composants lorsque les valeurs proviennent de variables :

// Good for dynamic locales
const locale = new Intl.Locale(userLanguage, {
  region: userRegion
});

Le constructeur valide les composants et crée un identifiant correctement formaté.

Compatibilité navigateur

Le constructeur Intl.Locale fonctionne dans tous les navigateurs modernes. Chrome, Firefox, Safari et Edge prennent en charge le constructeur et l'objet d'options pour construire des locales à partir de composants.

Node.js prend en charge Intl.Locale à partir de la version 12, avec une prise en charge complète de toutes les options du constructeur dans la version 14 et ultérieures.

Résumé

Le constructeur Intl.Locale construit des identifiants de locale à partir de composants individuels. Vous passez le code de langue comme premier argument et fournissez le script, la région et les préférences de formatage dans un objet d'options.

Concepts clés :

  • Les identifiants de locale se composent de composants langue, script et région
  • Le constructeur accepte un objet d'options avec les propriétés language, script et region
  • Vous pouvez remplacer les composants d'une locale existante en la passant comme premier argument
  • Les préférences de formatage comme calendar et hourCycle apparaissent sous forme d'extensions Unicode
  • La méthode toString() retourne la chaîne d'identifiant complète
  • Les propriétés comme language, region et script vous permettent de lire les composants
  • Le constructeur valide la syntaxe mais pas l'exactitude sémantique

Utilisez cette approche lors de la construction de locales à partir de saisies utilisateur, de la génération de variantes régionales ou de la combinaison de sélections distinctes de langue et de région. Pour les locales fixes, utilisez plutôt des littéraux de chaîne.