Comment construire des identifiants de locale à partir de composants

Construire des identifiants de locale en combinant des codes de langue, de script 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, le script 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 d'un identifiant de locale

Les identifiants de locale se composent d'éléments 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 de script spécifie le système d'écriture. Il utilise quatre lettres avec la première lettre en majuscule, selon la norme ISO 15924 :

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

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 script, puis région. Par exemple, zh-Hans-CN signifie langue chinoise, script simplifié, région Chine.

Construction de 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 le script car chaque langue possède un script 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());
// Résultat : "en-US"

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

Vous pouvez créer 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.

Construction de locales avec langue, script et région

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

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

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

console.log(simplifiedChinese.toString());
// Résultat : "zh-Hans-CN"

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

Le chinois traditionnel utilise un script et une région différents :

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

console.log(traditionalChinese.toString());
// Résultat : "zh-Hant-TW"

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

Le serbe utilise à la fois les scripts cyrillique et latin. Vous devez spécifier quel script 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.

Construction des locales à partir des sélections utilisateur

Les interfaces utilisateur permettent souvent aux utilisateurs de sélectionner séparément la langue et la région. 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);
// Résultat : "es-MX"

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

Vous pouvez valider les sélections en capturant 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);
// Résultat : { success: true, locale: "fr-CA" }

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

Le constructeur lance une erreur RangeError si un composant est invalide.

Construction des locales avec des composants optionnels

Chaque locale n'a pas besoin de tous les composants. Vous pouvez omettre les composants qui ne sont pas requis.

Une locale avec uniquement la langue omet la région et le script :

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

Cela représente le français sans spécifier une région ou un script particulier.

Vous pouvez inclure conditionnellement des composants en fonction des entrées 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"));
// Résultat : "en"

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

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

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

Remplacement de composants dans les 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());
// Résultat : "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());
// Résultat : "zh-Hant-TW"

Cela change à la fois le script et la région tout en préservant la langue.

Ajout de préférences de formatage aux locales construites

Au-delà de la langue, du script et de la région, les locales peuvent inclure des préférences de formatage. Ces préférences contrôlent l'apparence des dates, des nombres et d'autres valeurs.

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());
// Résultat : "ar-SA-u-ca-islamic"

console.log(locale.calendar);
// Résultat : "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());
// Résultat : "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));
// Résultat : "١٢٬٣٤٥" (chiffres arabo-indiens)

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 des locales réelles.

Le constructeur valide la syntaxe mais pas la pertinence sémantique :

// Syntaxiquement valide mais sémantiquement discutable
const locale = new Intl.Locale("en", {
  script: "Arab",
  region: "JP"
});

console.log(locale.toString());
// Résultat : "en-Arab-JP"

Ceci construit une locale pour l'anglais en script arabe au Japon. L'identifiant est valide selon BCP 47, mais ne représente pas une locale existant dans le 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());
// Résultat : "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 des locales construites

Après avoir construit une locale, vous pouvez lire ses composants comme des propriétés.

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

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

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

const locale = new Intl.Locale("fr", { region: "CA" });
console.log(locale.region);
// Résultat : "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);
// Résultat : "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);
// Résultat : undefined

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

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

console.log(locale.baseName);
// Résultat : "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 complet de la locale sous forme de chaîne de caractères :

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

console.log(identifier);
// Résultat : "es-MX"

Vous pouvez utiliser cette 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));
// Résultat : "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 lorsque nécessaire.

Cas d'utilisation 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 séparément la langue et la région. 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();
}

// L'utilisateur sélectionne "Espagnol" et "Mexique"
const selectedLocale = createLocaleFromPicker(
  { value: "es" },
  { value: "MX" }
);

console.log(selectedLocale);
// Résultat : "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);
// Résultat : ["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 des paramètres d'URL

Les URLs encodent souvent les préférences de locale en tant que 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 (séparateur invalide)

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" (format 24 heures)

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

Quand construire des locales à partir de composants

La construction de 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 des entrées utilisateur, ou lors de la génération programmatique de variantes de locale.

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

// Bon pour les locales fixes
const locale = new Intl.Locale("en-US");

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

// Bon pour les locales dynamiques
const locale = new Intl.Locale(userLanguage, {
  region: userRegion
});

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

Prise en charge des navigateurs

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 créer 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 de langue, de script et de région
  • Le constructeur accepte un objet d'options avec les propriétés language, script et region
  • Vous pouvez remplacer des composants d'une locale existante en la passant comme premier argument
  • Les préférences de formatage comme calendar et hourCycle apparaissent comme des extensions Unicode
  • La méthode toString() renvoie 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 la correction sémantique

Utilisez cette approche lors de la création de locales à partir d'entrées utilisateur, de la génération de variantes régionales ou de la combinaison de sélections de langue et de région séparées. Pour les locales fixes, utilisez plutôt des littéraux de chaîne.