L'API JavaScript Intl (Internationalisation)
Apprenez l'API JavaScript Intl pour formater nombres, devises, dates, temps relatifs, listes et pluriels selon la locale, et trier des chaînes correctement grâce à la comparaison tenant compte de la locale.
Intl est un espace de noms JavaScript intégré pour le formatage et la comparaison tenant compte de la locale. Aucune bibliothèque à installer, rien à importer — il est livré avec chaque navigateur moderne et avec Node.js. Grâce à lui, vous pouvez formater des nombres, des devises, des dates, des temps relatifs et des listes exactement comme les utilisateurs d'une région donnée s'y attendent, et vous pouvez trier du texte correctement pour des langues que le tri anglophone seul traite mal.
Presque tous les constructeurs Intl suivent la même forme : vous passez une locale (ou un tableau de locales de repli) et un objet options. Une locale est un code de langue BCP 47 tel que 'en-US', 'de-DE', 'fr-FR' ou 'ja-JP'. Si vous omettez totalement la locale, Intl utilise la locale par défaut du moteur d'exécution (le paramètre de langue du navigateur, ou la locale système dans Node).
// locale + options
new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' });
// no locale → uses the runtime default
new Intl.NumberFormat();
// an array provides fallbacks: try Welsh, then fall back to English
new Intl.NumberFormat(['cy', 'en']);Intl.NumberFormat
Intl.NumberFormat formate des nombres selon les conventions d'une locale. C'est important car les séparateurs de groupement et de décimale diffèrent d'un endroit à l'autre : le nombre 1234.56 s'écrit 1,234.56 aux États-Unis mais 1.234,56 en Allemagne.
const n = 1234.56;
console.log(new Intl.NumberFormat('en-US').format(n)); // "1,234.56"
console.log(new Intl.NumberFormat('de-DE').format(n)); // "1.234,56"
console.log(new Intl.NumberFormat('fr-FR').format(n)); // "1 234,56"L'option style sélectionne le type de valeur à formater : 'decimal' (par défaut), 'currency', 'percent' ou 'unit'.
Devise
Pour l'argent, définissez style: 'currency' et nommez la devise avec l'option currency (un code ISO 4217 tel que 'USD' ou 'EUR'). La locale décide de la position du symbole et des séparateurs.
const price = 1499.9;
console.log(
new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(price)
); // "$1,499.90"
console.log(
new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(price)
); // "1.499,90 €"
console.log(
new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(price)
); // "¥1,500" (yen has no minor unit, so it is rounded)Pourcentage, chiffres décimaux et notation compacte
Utilisez style: 'percent' pour formater un ratio en pourcentage — la valeur est multipliée par 100. Contrôlez le nombre de décimales affichées avec minimumFractionDigits et maximumFractionDigits. Définissez notation: 'compact' pour produire des formes courtes comme 1.2K et 3.4M.
console.log(
new Intl.NumberFormat('en-US', { style: 'percent' }).format(0.1875)
); // "19%"
console.log(
new Intl.NumberFormat('en-US', {
style: 'percent',
minimumFractionDigits: 2,
}).format(0.1875)
); // "18.75%"
console.log(
new Intl.NumberFormat('en-US', { notation: 'compact' }).format(1200000)
); // "1.2M"Unités
Avec style: 'unit', vous pouvez formater des mesures. Nommez l'unité avec l'option unit (par exemple 'kilometer-per-hour' ou 'megabyte') et choisissez un unitDisplay parmi 'short', 'long' ou 'narrow'.
console.log(
new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer-per-hour',
}).format(90)
); // "90 km/h"
console.log(
new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'megabyte',
unitDisplay: 'long',
}).format(16)
); // "16 megabytes"Pour un travail plus approfondi sur les nombres — arrondi, précision et arithmétique — consultez Numbers et JavaScript Math.
Intl.DateTimeFormat
Intl.DateTimeFormat formate des objets Date (et des horodatages) pour une locale. L'approche la plus rapide consiste à utiliser les options dateStyle et timeStyle, qui acceptent chacune 'full', 'long', 'medium' ou 'short'.
Pour un contrôle plus fin, définissez des composants individuels tels que year, month, day, hour, minute et second, et ancrez la sortie à un fuseau horaire avec timeZone.
const date = new Date('2026-06-19T14:30:00Z');
const fmt = new Intl.DateTimeFormat('en-GB', {
year: 'numeric',
month: 'short',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
timeZone: 'Europe/Berlin',
});
console.log(fmt.format(date)); // "19 Jun 2026, 16:30"Deux méthodes supplémentaires méritent d'être connues. .formatToParts() retourne la sortie décomposée en éléments étiquetés ({ type: 'month', value: 'Jun' }, etc.), ce qui vous permet de restyliser des parties individuelles. .formatRange(start, end) formate un intervalle de dates de manière compacte, en fusionnant les parties communes.
const fmt = new Intl.DateTimeFormat('en-US', { month: 'long', day: 'numeric' });
console.log(fmt.formatRange(new Date(2026, 5, 1), new Date(2026, 5, 5)));
// "June 1 – 5"Pour tout savoir sur la création et la manipulation des dates, consultez JavaScript Date.
Intl.RelativeTimeFormat
Intl.RelativeTimeFormat produit des expressions humaines comme "il y a 2 jours" ou "dans 3 heures". Vous appelez .format(value, unit), où une value négative représente le passé et une value positive l'avenir. L'option numeric: 'auto' permet au formateur d'utiliser des mots comme "hier" et "demain" au lieu de "il y a 1 jour".
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
console.log(rtf.format(-1, 'day')); // "yesterday"
console.log(rtf.format(3, 'hour')); // "in 3 hours"
console.log(rtf.format(-2, 'day')); // "2 days ago"
console.log(rtf.format(1, 'week')); // "next week"Le même appel dans une autre locale produit une formulation native — new Intl.RelativeTimeFormat('fr').format(-1, 'day') donne "il y a 1 jour".
Intl.Collator
Le tri de texte est l'endroit où le code naïf se trompe le plus souvent. Le Array.prototype.sort() par défaut de JavaScript compare les chaînes par leurs unités de code UTF-16, et non selon des règles alphabétiques. Cela signifie que les lettres majuscules se retrouvent avant les minuscules, et les lettres accentuées ou non latines apparaissent à des endroits surprenants.
const words = ['Zürich', 'apple', 'Banana', 'Älpler'];
console.log([...words].sort());
// ["Banana", "Zürich", "Älpler", "apple"] ← not what a reader expectsIntl.Collator corrige cela en comparant les chaînes comme le ferait une langue donnée. Sa méthode .compare possède exactement la signature attendue par sort(), vous pouvez donc la passer directement.
Pour une comparaison ponctuelle de deux chaînes, vous pouvez également utiliser String.prototype.localeCompare, qui accepte les mêmes arguments de locale et d'options : 'ä'.localeCompare('z', 'de'). Lorsque vous triez un tableau entier, préférez un Intl.Collator réutilisé — c'est plus rapide qu'appeler localeCompare pour chaque paire. Consultez Strings pour en savoir plus sur le travail avec le texte.
Intl.PluralRules
Les différentes langues ont des catégories de pluriel différentes. L'anglais n'en a que deux ('one' et 'other'), mais beaucoup de langues en ont davantage. Intl.PluralRules vous indique dans quelle catégorie tombe un nombre afin que vous puissiez sélectionner la bonne formulation dans un message traduit.
const pr = new Intl.PluralRules('en-US');
console.log(pr.select(0)); // "other"
console.log(pr.select(1)); // "one"
console.log(pr.select(5)); // "other"
function items(count) {
const word = pr.select(count) === 'one' ? 'item' : 'items';
return `${count} ${word}`;
}
console.log(items(1)); // "1 item"
console.log(items(3)); // "3 items"Intl.ListFormat
Intl.ListFormat joint un array de chaînes en une liste à la sonorité naturelle, en insérant les séparateurs et la conjonction appropriés pour la locale — y compris la virgule d'Oxford là où la langue l'utilise.
const items = ['apples', 'bananas', 'oranges'];
const en = new Intl.ListFormat('en-US', { style: 'long', type: 'conjunction' });
console.log(en.format(items)); // "apples, bananas, and oranges"
const enOr = new Intl.ListFormat('en-US', { type: 'disjunction' });
console.log(enOr.format(items)); // "apples, bananas, or oranges"
const de = new Intl.ListFormat('de-DE', { type: 'conjunction' });
console.log(de.format(items)); // "apples, bananas und oranges"Réutiliser les formateurs pour la performance
Construire un formateur Intl est relativement coûteux — cela charge et résout les données de locale. Créez chaque formateur une seule fois et réutilisez-le, en particulier dans les boucles ou lors du rendu de listes. Construire un nouveau new Intl.NumberFormat(...) pour chaque ligne peut être bien plus lent que le formatage lui-même.
// Slow: a new formatter is built on every iteration
prices.forEach((p) =>
console.log(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(p))
);
// Fast: build it once, reuse it
const money = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });
prices.forEach((p) => console.log(money.format(p)));Chaque formateur expose également .resolvedOptions(), qui indique la locale et les options réellement choisies après négociation. C'est utile pour déboguer les cas où le moteur d'exécution se replie sur une locale autre que celle que vous avez demandée.
Récapitulatif
L'API Intl couvre les tâches de formatage et de comparaison qui nécessitaient autrefois des bibliothèques tierces volumineuses : nombres tenant compte de la locale, devises, dates, temps relatifs, pluriels et listes, ainsi que le tri correct du texte via Intl.Collator. Puisqu'elle est intégrée dans chaque navigateur moderne et dans Node.js, l'utiliser en priorité maintient votre bundle léger et votre sortie correcte pour les utilisateurs du monde entier. Retenez la règle la plus payante : construisez chaque formateur une seule fois et réutilisez-le.