Une locale est l’ensemble des paramètres décrivant la langue, la région et les préférences de formatage d’un utilisateur. Elle répond à la question « qui est cette personne et comment le contenu doit-il lui être présenté », et elle contrôle bien plus que la simple langue des mots.
Une locale se compose généralement d’au moins un identifiant linguistique et un identifiant régional : anglais + États-Unis donne en-US.
Ce qu’une locale contrôle réellement
La langue est la partie visible. C’est dans le reste que se cachent les bugs.
| Aspect | en-US |
de-DE |
fr-CA |
ar-EG |
|---|---|---|---|---|
| Date | 3/4/2026 | 4.3.2026 | 2026-03-04 | ٤/٣/٢٠٢٦ |
| Séparateur décimal | 1,234.56 | 1.234,56 | 1 234,56 | ١٢٣٤٫٥٦ |
| Devise | $1,234.56 | 1.234,56 € | 1 234,56 $ | ١٢٣٤٫٥٦ ج.م. |
| Premier jour de la semaine | dimanche | lundi | dimanche | samedi |
| Sens de lecture | LTR | LTR | LTR | RTL |
| Formes de pluriel | 2 | 2 | 2 | 6 |
Regardez la cellule en haut à gauche par rapport à la troisième colonne : 3/4/2026 correspond au 4 mars aux États-Unis et au 3 avril dans presque tout le reste du monde. Une date affichée sans tenir compte de la locale n’est pas simplement moche, elle est fausse d’une manière que personne ne remarque jusqu’à ce qu’une réservation se retrouve décalée d’un mois.
Au-delà du formatage, une locale détermine :
- Le tri. Le suédois classe ä après z ; l’allemand le classe avec a. Un tri par ordre des octets est faux dans les deux cas, et « faux » signifie ici qu’un utilisateur ne parvient pas à retrouver son propre nom dans une liste.
- La conversion de casse. Le turc possède un i pointé et un i non pointé, si bien que mettre
ien majuscule donneİentretIpartout ailleurs. Cela casse la comparaison insensible à la casse d’une manière qui a déjà mis de vrais systèmes à terre. - Les catégories de pluriel. Le nombre de formes dont un message a besoin, de une à six.
- L’ordre des noms et des adresses, les unités de mesure, les formats de numéros de téléphone, le format de papier.
Comment une balise de langue est construite
BCP 47 est la norme IETF qui en définit la structure. Les sous-balises vont du plus général au plus spécifique, séparées par des traits d’union :
language[-Script][-REGION][-variant]
| Sous-balise | Norme | Convention | Exemples |
|---|---|---|---|
| Langue | ISO 639-1, sinon 639-2/3 | minuscules | en, fr, zh, fil |
| Écriture | ISO 15924 | Casse de titre, quatre lettres | Latn, Cyrl, Arab, Hans |
| Région | ISO 3166-1 alpha-2, ou UN M.49 | MAJUSCULES | GB, CA, BR, 419 |
| Variante | Registre IANA | minuscules | valencia, 1901 |
Lecture de quelques balises réelles :
pt-BR— le portugais tel qu’écrit au Brésil.sr-Latn-RS— le serbe, écriture latine, Serbie. Le serbe s’écrit à la fois en cyrillique et en latin, donc la sous-balise d’écriture fait un vrai travail.es-419— l’espagnol pour l’Amérique latine.419est un code de région UN M.49 couvrant un continent plutôt qu’un pays, ce qui est exactement ce qu’il faut lorsque l’alternative consiste à choisir arbitrairement un seul pays.zh-Hans— le chinois simplifié, sans région. C’est généralement ce que vous voulez, car le chinois se divise par écriture plutôt que par pays.
Les balises sont formellement insensibles à la casse, mais suivez tout de même les conventions de casse : de nombreux logiciels qui lisent vos fichiers sont plus stricts que la norme qu’ils prétendent implémenter.
Le séparateur est un trait d’union dans la norme et un underscore dans POSIX, Java et les noms de fichiers gettext — une divergence qui a sa propre longue histoire, traitée dans en-GB contre en_GB.
Choisir le bon niveau de précision
L’erreur de conception la plus courante consiste à être plus précis que ce que vous pouvez réellement prendre en charge. Ajouter en-US, en-GB, en-AU et en-CA signifie quatre ensembles de traductions à maintenir, et si vous ne faites varier l’orthographe que dans deux d’entre eux, vous avez créé les trois quarts du travail pour un quart du bénéfice.
Quelques heuristiques utiles :
Commencez par la langue seule (fr, es, de) sauf si vous avez une raison concrète de la diviser. Vous pouvez ajouter des régions plus tard ; les fusionner ensuite est plus difficile.
Divisez lorsque le contenu diffère réellement. pt-BR et pt-PT diffèrent suffisamment en vocabulaire et en grammaire pour que les utilisateurs brésiliens remarquent immédiatement le portugais européen. es-ES et es-MX diffèrent de manière significative. en-US et en-CA, dans l’ensemble, non.
Divisez par écriture lorsque la langue en utilise plusieurs. zh-Hans / zh-Hant, sr-Latn / sr-Cyrl. C’est un véritable problème de compréhension de lecture, pas une simple préférence.
Laissez le formatage et la traduction varier indépendamment. Un utilisateur peut vouloir un texte en français avec des formats de date canadiens. Le formatage vient de la locale ; la traduction peut venir d’une locale parente — c’est justement à cela que sert le fallback.
Fallback et mise en correspondance
Les utilisateurs arrivent avec une préférence qui ne correspond pas forcément exactement à ce que vous prenez en charge. Un navigateur envoie :
Accept-Language: fr-CA, fr;q=0.9, en;q=0.8
À lire comme : français canadien préféré, puis n’importe quel français, puis l’anglais. Les règles de résolution méritent d’être implémentées correctement plutôt qu’à la main :
Lookup prend la balise demandée et la tronque progressivement jusqu’à trouver une correspondance : fr-CA → fr → valeur par défaut. Simple, et généralement juste.
Filtering renvoie tout ce qui correspond à un préfixe — demander fr donne fr, fr-CA, fr-BE. Utile pour proposer un choix à l’utilisateur.
Le piège, c’est que la troncature n’est pas toujours correcte. zh-Hant-HK tronqué en zh peut tomber sur le simplifié, que ne peut pas lire confortablement un lecteur du traditionnel. CLDR publie des données de fallback explicites pour ces cas, et toute bibliothèque i18n mature les utilise.
L’héritage est la même idée appliquée à votre propre contenu. Définissez un français générique dans fr, puis créez fr-CA en n’y portant que les chaînes qui diffèrent réellement, et laissez le reste hériter. Vous maintenez une traduction complète plus une petite delta, au lieu de deux traductions complètes qui finissent par diverger. WebTranslateIt implémente cela directement : les fichiers d’une langue héritée peuvent soit inclure les traductions de la langue parente, soit ne contenir que les différences, le reste étant laissé à null.
Locales personnalisées
Il arrive que vous ayez besoin d’une locale qui n’existe pas. Le cas courant est une étape de relecture : une pseudo-langue en-dev contenant le texte rédigé par les développeurs, à réécrire par un professionnel avant traduction. Un autre cas est la pseudo-localisation, qui utilise une fausse locale pour vérifier que l’internationalisation a réellement fonctionné.
WebTranslateIt prend en charge cela en partant d’une langue de base et en y ajoutant un code de suffixe et une description, produisant par exemple en_dev nommé « English by developers ».
Les codes de locale les plus souvent mal utilisés
Une courte liste de ceux qui reviennent souvent, car chacun a déjà coûté une sortie à quelqu’un :
en-UKn’existe pas. Le code ISO 3166 du Royaume-Uni estGB.zh-CNsignifiait autrefois simplifié. Il le sous-entend sans le dire, et laisse sans correspondance les lecteurs du simplifié à Singapour et en Malaisie. Utilisezzh-Hans.iw,in,ji,jwsont les codes antérieurs à 1989 pour l’hébreu, l’indonésien, le yiddish et le javanais. L’ISO les a renommés ; Java a figé les anciens codes par compatibilité et renvoie encoreiwpourLocale("he"). Normalisez explicitement ces alias à toute frontière JVM.- Un code de pays n’est pas un code de langue.
ATdésigne l’Autriche ; la locale estde-AT. Cela se voit lorsqu’un sélecteur de pays est branché directement sur une recherche de locale. nocontrenb/nn. Le norvégien possède deux normes écrites, le bokmål et le nynorsk.noest la macrolangue ;nbest ce que la plupart du contenu est réellement.
Règles pratiques
- Stockez les locales sous forme BCP 47 avec traits d’union. Convertissez en underscores uniquement à la frontière du système de fichiers, pour les outils qui en ont besoin.
- Normalisez une seule fois, en périphérie. Ne laissez jamais une chaîne de locale brute provenant d’une saisie utilisateur ou d’une API tierce atteindre vos tables de correspondance.
- Ne construisez jamais une locale en concaténant un sélecteur de langue et un sélecteur de pays.
de-BRa l’apparence d’une balise valide pour une combinaison que personne ne prend en charge. - Ne déduisez pas la locale de la seule adresse IP. Un germanophone au Japon veut du contenu en allemand. Utilisez
Accept-Language, mémorisez le choix explicite de l’utilisateur, et traitez la géographie tout au plus comme un indice faible. - Séparez la locale de formatage et la locale de contenu dans votre modèle de données. Elles divergent plus souvent qu’on ne le pense.
Frequently asked questions
- Qu’est-ce qu’une locale ?
- Une locale est l’ensemble des paramètres décrivant la langue, la région et les préférences de formatage d’un utilisateur. Elle détermine non seulement la langue dans laquelle le texte apparaît, mais aussi comment les dates, les nombres, les devises et les noms sont formatés, comment les chaînes sont triées, et quelles formes de pluriel s’appliquent.
- Quelle est la différence entre une langue et une locale ?
- Une langue identifie les mots (fr). Une locale ajoute la région, l’écriture ou la variante qui change la manière dont la langue est écrite ou formatée (fr-CA). Le français au Canada et le français en France partagent la même langue et diffèrent par le vocabulaire, le format de date et certaines orthographes.
- Qu’est-ce que BCP 47 ?
- BCP 47 est la norme IETF définissant la structure des balises de langue — une sous-balise de langue suivie de sous-balises facultatives d’écriture, de région et de variante, séparées par des traits d’union, comme dans sr-Latn-RS. C’est ce qu’attendent les attributs HTML lang, les en-têtes HTTP Accept-Language et les API JavaScript Intl.
- Dois-je utiliser zh-CN ou zh-Hans ?
- Préférez zh-Hans pour le chinois simplifié et zh-Hant pour le traditionnel. Le chinois se divise par écriture plutôt que par pays, donc une balise de région comme zh-CN ne fait que sous-entendre l’écriture et laisse sans correspondance les lecteurs du chinois simplifié situés ailleurs.
Keep reading
-
en-GB vs en_GB : trait d’union ou underscore dans les codes de locale ?
La norme dit trait d’union, la moitié de votre chaîne d’outils dit underscore. Voici le format attendu par chaque écosystème, pourquoi cette scission existe, et comment passer de l’un à l’autre sans rien casser.
-
Règles de pluriel par langue : le guide CLDR complet
Un tableau de référence des catégories de pluriel CLDR pour 163 langues, plus pourquoi one ne veut pas dire 1 et comment chaque framework i18n attend que vous écriviez les règles.
-
i18n vs l10n : quelle est la différence ?
L’internationalisation est le travail d’ingénierie qui rend la traduction possible. La localisation est la traduction elle-même. Voici où passe la frontière et pourquoi elle compte.
-
Codes de locale, balises de langue et règles de pluriel (documentation)
Créer des locales dans WebTranslateIt, les locales personnalisées, et l’héritage entre langues.
Translate your app without the spreadsheet round-trip
WebTranslateIt reads the file formats and placeholder syntax described on this page, validates them as translators work, and syncs the results straight back into your repository.