Comment extraire la langue, le pays et l'écriture d'une locale

Utilisez JavaScript pour analyser les identifiants de locale et accéder à leurs composants individuels

Introduction

Les identifiants de locale comme en-US, fr-CA et zh-Hans-CN encodent plusieurs informations dans une seule chaîne de caractères. Ces composants indiquent la langue utilisée, la région où elle est parlée et parfois le système d'écriture.

Lors de la création d'applications internationalisées, vous devez souvent extraire ces composants individuels. Vous pouvez vouloir afficher uniquement le nom de la langue aux utilisateurs, regrouper les locales par région ou vérifier quel système d'écriture une locale utilise. Au lieu d'analyser les chaînes manuellement avec des expressions régulières, JavaScript fournit l'API Intl.Locale pour extraire les composants de manière fiable.

Ce guide explique quels composants existent dans les identifiants de locale, comment les extraire à l'aide de l'API Intl.Locale et quand vous auriez besoin d'utiliser ces composants en pratique.

Quels composants existent dans les identifiants de locale

Les identifiants de locale suivent la norme BCP 47, qui définit une structure pour décrire les langues et les variations régionales. Un identifiant de locale complet peut contenir plusieurs composants séparés par des traits d'union.

Les trois composants les plus courants sont :

  • Langue : la langue principale utilisée, comme l'anglais, l'espagnol ou le chinois
  • Région : la zone géographique où la langue est utilisée, comme les États-Unis, le Canada ou la Chine
  • Écriture : le système d'écriture utilisé pour représenter la langue, comme les caractères latins, cyrilliques ou han

Un identifiant de locale simple contient uniquement un code de langue :

en

La plupart des identifiants de locale incluent une langue et une région :

en-US
fr-CA
es-MX

Certains identifiants de locale incluent un script lorsque la langue peut être écrite dans plusieurs systèmes d'écriture :

zh-Hans-CN
zh-Hant-TW
sr-Cyrl-RS
sr-Latn-RS

Comprendre ces composants vous aide à prendre des décisions concernant le repli linguistique, la sélection de contenu et la personnalisation de l'interface utilisateur.

Utiliser Intl.Locale pour extraire les composants

L'API Intl.Locale convertit les chaînes d'identifiants de locale en objets structurés. Une fois que vous créez un objet locale, vous pouvez lire ses composants via des propriétés.

Créez un objet locale en passant l'identifiant au constructeur :

const locale = new Intl.Locale("en-US");

console.log(locale.language); // "en"
console.log(locale.region); // "US"

L'objet locale expose des propriétés qui correspondent à chaque composant de l'identifiant. Ces propriétés fournissent un accès structuré sans nécessiter d'analyse de chaîne.

Extraire le code de langue

La propriété language renvoie le composant langue de l'identifiant de locale. Il s'agit du code à deux ou trois lettres qui identifie la langue principale.

const english = new Intl.Locale("en-US");
console.log(english.language); // "en"

const french = new Intl.Locale("fr-CA");
console.log(french.language); // "fr"

const chinese = new Intl.Locale("zh-Hans-CN");
console.log(chinese.language); // "zh"

Les codes de langue suivent la norme ISO 639. Les codes courants incluent en pour l'anglais, es pour l'espagnol, fr pour le français, de pour l'allemand, ja pour le japonais et zh pour le chinois.

Le code de langue est toujours présent dans un identifiant de locale valide. C'est le seul composant obligatoire.

const languageOnly = new Intl.Locale("ja");
console.log(languageOnly.language); // "ja"
console.log(languageOnly.region); // undefined

Lorsque vous extrayez le code de langue, vous pouvez l'utiliser pour sélectionner des traductions, déterminer les règles de traitement du texte ou créer des sélecteurs de langue pour les utilisateurs.

Extraire le code de région

La propriété region renvoie le composant région de l'identifiant de locale. Il s'agit du code à deux lettres qui identifie la zone géographique où la langue est utilisée.

const americanEnglish = new Intl.Locale("en-US");
console.log(americanEnglish.region); // "US"

const britishEnglish = new Intl.Locale("en-GB");
console.log(britishEnglish.region); // "GB"

const canadianFrench = new Intl.Locale("fr-CA");
console.log(canadianFrench.region); // "CA"

Les codes de région suivent la norme ISO 3166-1. Ils utilisent deux lettres majuscules pour représenter les pays et territoires. Les codes courants incluent US pour les États-Unis, GB pour le Royaume-Uni, CA pour le Canada, MX pour le Mexique, FR pour la France et CN pour la Chine.

Le code de région modifie la façon dont les dates, les nombres et les devises sont formatés. L'anglais américain utilise les dates au format mois-jour-année et les points comme séparateurs décimaux. L'anglais britannique utilise les dates au format jour-mois-année et les virgules comme séparateurs de milliers.

Les codes de région sont facultatifs dans les identifiants de locale. Lorsqu'une locale n'a pas de région, la propriété region renvoie undefined :

const genericSpanish = new Intl.Locale("es");
console.log(genericSpanish.region); // undefined

Lorsque vous extrayez le code de région, vous pouvez l'utiliser pour personnaliser le formatage régional, sélectionner du contenu spécifique à une région ou afficher des informations de localisation aux utilisateurs.

Extraction du code d'écriture

La propriété script renvoie le composant d'écriture de l'identifiant de locale. Il s'agit du code à quatre lettres qui identifie le système d'écriture utilisé pour représenter la langue.

const simplifiedChinese = new Intl.Locale("zh-Hans-CN");
console.log(simplifiedChinese.script); // "Hans"

const traditionalChinese = new Intl.Locale("zh-Hant-TW");
console.log(traditionalChinese.script); // "Hant"

const serbianCyrillic = new Intl.Locale("sr-Cyrl-RS");
console.log(serbianCyrillic.script); // "Cyrl"

const serbianLatin = new Intl.Locale("sr-Latn-RS");
console.log(serbianLatin.script); // "Latn"

Les codes d'écriture suivent la norme ISO 15924. Ils utilisent quatre lettres avec la première lettre en majuscule. Les codes courants incluent Latn pour l'écriture latine, Cyrl pour l'écriture cyrillique, Hans pour les caractères han simplifiés, Hant pour les caractères han traditionnels et Arab pour l'écriture arabe.

La plupart des locales omettent le code d'écriture car chaque langue possède un système d'écriture par défaut. L'anglais utilise par défaut l'écriture latine, vous écrivez donc en au lieu de en-Latn. Le russe utilise par défaut le cyrillique, vous écrivez donc ru au lieu de ru-Cyrl.

Les codes d'écriture apparaissent lorsqu'une langue peut être écrite de plusieurs façons. Le chinois utilise à la fois des caractères simplifiés et traditionnels. Le serbe utilise à la fois les alphabets cyrillique et latin. Dans ces cas, le code d'écriture permet de lever l'ambiguïté sur le système d'écriture à utiliser.

Lorsque la locale n'a pas de code d'écriture explicite, la propriété script renvoie undefined :

const english = new Intl.Locale("en-US");
console.log(english.script); // undefined

Lorsque vous extrayez le code d'écriture, vous pouvez l'utiliser pour sélectionner des polices, déterminer le rendu du texte ou filtrer le contenu par système d'écriture.

Comprendre quand les composants sont indéfinis

Tous les identifiants de locale n'incluent pas tous les composants. Le code de langue est obligatoire, mais la région et l'écriture sont facultatifs.

Lorsqu'un composant n'est pas présent dans l'identifiant, la propriété correspondante renvoie undefined :

const locale = new Intl.Locale("fr");

console.log(locale.language); // "fr"
console.log(locale.region); // undefined
console.log(locale.script); // undefined

Ce comportement vous permet de vérifier si une locale spécifie une région ou une écriture avant d'utiliser ces valeurs :

const locale = new Intl.Locale("en-US");

if (locale.region) {
  console.log(`Region-specific formatting for ${locale.region}`);
} else {
  console.log("Using default formatting");
}

Vous pouvez utiliser l'opérateur de coalescence nulle pour fournir des valeurs par défaut :

const locale = new Intl.Locale("es");
const region = locale.region ?? "ES";

console.log(region); // "ES"

Lors de la construction de chaînes de repli de locale, la vérification des composants indéfinis vous aide à construire des alternatives :

function buildFallbackChain(identifier) {
  const locale = new Intl.Locale(identifier);
  const fallbacks = [identifier];

  if (locale.region) {
    fallbacks.push(locale.language);
  }

  return fallbacks;
}

console.log(buildFallbackChain("fr-CA")); // ["fr-CA", "fr"]
console.log(buildFallbackChain("fr")); // ["fr"]

Cela crée une liste d'identifiants de locale ordonnés du plus spécifique au plus général.

Cas d'usage pratiques pour l'extraction de composants

L'extraction de composants de locale résout plusieurs problèmes courants lors de la création d'applications internationalisées.

Regrouper les locales par langue

Lors de l'affichage d'une liste de langues disponibles, regroupez les locales qui partagent le même code de langue :

const locales = ["en-US", "en-GB", "fr-FR", "fr-CA", "es-ES", "es-MX"];

const grouped = locales.reduce((groups, identifier) => {
  const locale = new Intl.Locale(identifier);
  const language = locale.language;

  if (!groups[language]) {
    groups[language] = [];
  }

  groups[language].push(identifier);
  return groups;
}, {});

console.log(grouped);
// {
//   en: ["en-US", "en-GB"],
//   fr: ["fr-FR", "fr-CA"],
//   es: ["es-ES", "es-MX"]
// }

Cette organisation aide les utilisateurs à trouver leur variante régionale préférée au sein d'une langue.

Créer des sélecteurs de locale

Lors de la création d'une interface utilisateur pour la sélection de langue, extrayez les composants pour afficher des libellés significatifs :

function buildLocaleSelector(identifiers) {
  return identifiers.map(identifier => {
    const locale = new Intl.Locale(identifier);

    const languageNames = new Intl.DisplayNames([identifier], {
      type: "language"
    });

    const regionNames = new Intl.DisplayNames([identifier], {
      type: "region"
    });

    return {
      value: identifier,
      language: languageNames.of(locale.language),
      region: locale.region ? regionNames.of(locale.region) : null
    };
  });
}

const options = buildLocaleSelector(["en-US", "en-GB", "fr-FR"]);
console.log(options);
// [
//   { value: "en-US", language: "English", region: "United States" },
//   { value: "en-GB", language: "English", region: "United Kingdom" },
//   { value: "fr-FR", language: "French", region: "France" }
// ]

Cela fournit des libellés lisibles pour chaque option de locale.

Filtrage par région

Lorsque vous devez afficher du contenu spécifique à une région, extrayez le code de région pour filtrer les locales :

function filterByRegion(identifiers, targetRegion) {
  return identifiers.filter(identifier => {
    const locale = new Intl.Locale(identifier);
    return locale.region === targetRegion;
  });
}

const allLocales = ["en-US", "es-US", "en-GB", "fr-FR", "zh-CN"];
const usLocales = filterByRegion(allLocales, "US");

console.log(usLocales); // ["en-US", "es-US"]

Cela vous aide à sélectionner les locales appropriées pour les utilisateurs d'un pays spécifique.

Vérification de la compatibilité des scripts

Lors de la sélection de polices ou du rendu de texte, vérifiez le script pour garantir la compatibilité :

function selectFont(identifier) {
  const locale = new Intl.Locale(identifier);
  const script = locale.script;

  if (script === "Hans" || script === "Hant") {
    return "Noto Sans CJK";
  } else if (script === "Arab") {
    return "Noto Sans Arabic";
  } else if (script === "Cyrl") {
    return "Noto Sans";
  } else {
    return "Noto Sans";
  }
}

console.log(selectFont("zh-Hans-CN")); // "Noto Sans CJK"
console.log(selectFont("ar-SA")); // "Noto Sans Arabic"
console.log(selectFont("en-US")); // "Noto Sans"

Cela garantit que le texte s'affiche correctement pour chaque système d'écriture.

Implémentation du repli linguistique

Lorsque la locale préférée de l'utilisateur n'est pas disponible, revenez à la langue de base :

function selectBestLocale(userPreference, supportedLocales) {
  const user = new Intl.Locale(userPreference);

  if (supportedLocales.includes(userPreference)) {
    return userPreference;
  }

  const languageMatch = supportedLocales.find(supported => {
    const locale = new Intl.Locale(supported);
    return locale.language === user.language;
  });

  if (languageMatch) {
    return languageMatch;
  }

  return supportedLocales[0];
}

const supported = ["en-US", "fr-FR", "es-ES"];

console.log(selectBestLocale("en-GB", supported)); // "en-US"
console.log(selectBestLocale("fr-CA", supported)); // "fr-FR"
console.log(selectBestLocale("de-DE", supported)); // "en-US"

Cela fournit un repli élégant lorsque les correspondances exactes ne sont pas disponibles.