C’est une idée fausse commune que l’internationalisation (I18N) consiste simplement à traduire le texte. Bien que cruciale, la traduction n’est qu’une facette. L’une des complexités réside dans adapter des informations pour diverses attentes culturelles: Comment affichez-vous une date au Japon contre l’Allemagne? Quelle est la bonne façon de pluraliser un élément en arabe contre l’anglais? Comment triez-vous une liste de noms dans diverses langues?
De nombreux développeurs se sont appuyés sur des bibliothèques tierces lourdes ou, pire, des fonctions de mise en forme sur mesure pour relever ces défis. Ces solutions, bien que fonctionnelles, viennent souvent avec des frais généraux significatifs: la taille d’augmentation du faisceau, les goulots d’étranglement potentiels de performances et la lutte constante pour suivre les règles linguistiques et les données linguistiques en évolution.
Entrez dans API d’internationalisation ECMAScriptplus communément appelé Intl
objet. Cette puissance silencieuse, construite directement dans des environnements JavaScript modernes, est souvent sous-estimé, mais incroyablement solution puissante, native, performante et conforme aux normes pour gérer l’internationalisation des données. C’est un témoignage de l’engagement du Web à être mondialoffrant un moyen unifié et efficace de formater les nombres, les dates, les listes, etc., selon des lieux spécifiques.
Intl
Et les localités: plus que des codes linguistiques
Au cœur de Intl
réside le concept de lieu. Un lieu est bien plus qu’un simple code de langue à deux lettres (comme en
pour l’anglais ou es
pour l’espagnol). Il résume le contexte complet nécessaire pour présenter les informations de manière appropriée pour un groupe culturel spécifique. Cela comprend:
- Langue: Le milieu linguistique primaire (par exemple,
en
,es
,fr
). - Scénario: Le script (par exemple,
Latn
pour le latin,Cyrl
pour cyrillique). Par exemple,zh-Hans
pour chinois simplifié, vs.zh-Hant
pour le chinois traditionnel. - Région: La zone géographique (par exemple,
US
Pour les États-Unis,GB
pour la Grande-Bretagne,DE
pour l’Allemagne). Ceci est crucial pour les variations dans la même langue, commeen-US
contre.en-GB
qui diffèrent dans la date, l’heure et la mise en forme du nombre. - Préférences / variantes: D’autres préférences culturelles ou linguistiques spécifiques. Voir «Choisir une étiquette linguistique» de W3C pour plus d’informations.
En règle générale, vous voudrez choisir le lieu en fonction de la langue de la page Web. Cela peut être déterminé à partir du lang
attribut:
// Get the page's language from the HTML lang attribute
const pageLocale = document.documentElement.lang || 'en-US'; // Fallback to 'en-US'
Parfois, vous voudrez peut-être remplacer le paramètre régional de la page avec un lieu spécifique, par exemple lors de l’affichage du contenu en plusieurs langues:
// Force a specific locale regardless of page language
const tutorialFormatter = new Intl.NumberFormat('zh-CN', { style: 'currency', currency: 'CNY' });
console.log(`Chinese example: ${tutorialFormatter.format(199.99)}`); // Output: ¥199.99
Dans certains cas, vous voudrez peut-être utiliser le langage préféré de l’utilisateur:
// Use the user's preferred language
const browserLocale = navigator.language || 'ja-JP';
const formatter = new Intl.NumberFormat(browserLocale, { style: 'currency', currency: 'JPY' });
Lorsque vous instanciez un Intl
Formateur, vous pouvez éventuellement passer une ou plusieurs chaînes de paramètres régionaux. L’API sélectionnera ensuite les paramètres régionaux les plus appropriés en fonction de la disponibilité et des préférences.
Powerhouses de formatage central
Le Intl
Object expose plusieurs constructeurs, chacun pour une tâche de formatage spécifique. Plongeons les plus fréquemment utilisés, ainsi que des joyaux puissants et souvent négligés.
1 et 1 Intl.DateTimeFormat
: Dates et heures, à l’échelle mondiale
Les dates et les heures de mise en forme sont un problème I18N classique. Devrait-il être MM / DD / YYYY ou DD.MM.YYYY? Le mois devrait-il être un nombre ou un mot complet? Intl.DateTimeFormat
gère tout cela avec facilité.
const date = new Date(2025, 5, 27, 14, 30, 0); // June 27, 2025, 2:30 PM
// Specific locale and options (e.g., long date, short time)
const options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
timeZoneName: 'shortOffset' // e.g., "GMT+8"
};
console.log(new Intl.DateTimeFormat('en-US', options).format(date));
// "Friday, June 27, 2025 at 2:30 PM GMT+8"
console.log(new Intl.DateTimeFormat('de-DE', options).format(date));
// "Freitag, 27. Juni 2025 um 14:30 GMT+8"
// Using dateStyle and timeStyle for common patterns
console.log(new Intl.DateTimeFormat('en-GB', { dateStyle: 'full', timeStyle: 'short' }).format(date));
// "Friday 27 June 2025 at 14:30"
console.log(new Intl.DateTimeFormat('ja-JP', { dateStyle: 'long', timeStyle: 'short' }).format(date));
// "2025年6月27日 14:30"
La flexibilité de options
pour DateTimeFormat
est vaste, permettant le contrôle au cours de l’année, du mois, du jour, de la semaine, de l’heure, de la minute, du deuxième, du fuseau horaire, et plus encore.
2 Intl.NumberFormat
: Nombres avec des nuances culturelles
Au-delà de simples décimales, les nombres nécessitent une manipulation minutieuse: des milliers de séparateurs, des marqueurs décimaux, des symboles de devise et des panneaux de pourcentage varient sauvagement dans les lieux.
const price = 123456.789;
// Currency formatting
console.log(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(price));
// "$123,456.79" (auto-rounds)
console.log(new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(price));
// "123.456,79 €"
// Units
console.log(new Intl.NumberFormat('en-US', { style: 'unit', unit: 'meter', unitDisplay: 'long' }).format(100));
// "100 meters"
console.log(new Intl.NumberFormat('fr-FR', { style: 'unit', unit: 'kilogram', unitDisplay: 'short' }).format(5.5));
// "5,5 kg"
Des options comme minimumFractionDigits
, maximumFractionDigits
et notation
(par exemple, scientific
, compact
) fournir un contrôle encore plus fin.
3 et 3 Intl.ListFormat
: Listes de langues naturelles
La présentation de listes d’articles est étonnamment délicate. L’anglais utilise «et» pour la conjonction et «ou» pour la disjonction. De nombreuses langues ont des conjonctions différentes et certaines nécessitent une ponctuation spécifique.
Cette API simplifie une tâche qui nécessiterait autrement une logique conditionnelle complexe:
const items = ['apples', 'oranges', 'bananas'];
// Conjunction ("and") list
console.log(new Intl.ListFormat('en-US', { type: 'conjunction' }).format(items));
// "apples, oranges, and bananas"
console.log(new Intl.ListFormat('de-DE', { type: 'conjunction' }).format(items));
// "Äpfel, Orangen und Bananen"
// Disjunction ("or") list
console.log(new Intl.ListFormat('en-US', { type: 'disjunction' }).format(items));
// "apples, oranges, or bananas"
console.log(new Intl.ListFormat('fr-FR', { type: 'disjunction' }).format(items));
// "apples, oranges ou bananas"
4 Intl.RelativeTimeFormat
: Horodatage respectueux de l’homme
Afficher «il y a 2 jours» ou «en 3 mois» est courant dans l’interface utilisateur, mais la localisation de ces phrases nécessite avec précision des données étendues. Intl.RelativeTimeFormat
automatise cela.
const rtf = new Intl.RelativeTimeFormat('en-US', { numeric: 'auto' });
console.log(rtf.format(-1, 'day')); // "yesterday"
console.log(rtf.format(1, 'day')); // "tomorrow"
console.log(rtf.format(-7, 'day')); // "7 days ago"
console.log(rtf.format(3, 'month')); // "in 3 months"
console.log(rtf.format(-2, 'year')); // "2 years ago"
// French example:
const frRtf = new Intl.RelativeTimeFormat('fr-FR', { numeric: 'auto', style: 'long' });
console.log(frRtf.format(-1, 'day')); // "hier"
console.log(frRtf.format(1, 'day')); // "demain"
console.log(frRtf.format(-7, 'day')); // "il y a 7 jours"
console.log(frRtf.format(3, 'month')); // "dans 3 mois"
Le numeric: 'always'
L’option forcerait «il y a 1 jour» au lieu de «hier».
5 Intl.PluralRules
: Maîtrise la pluralisation
C’est sans doute l’un des aspects les plus critiques de I18n. Différentes langues ont des règles de pluralisation très différentes (par exemple, l’anglais a un singulier / pluriel, l’arabe n’a zéro, un, deux, beaucoup & mldR;). Intl.PluralRules
vous permet de déterminer la «catégorie plurielle» pour un nombre donné dans un lieu spécifique.
const prEn = new Intl.PluralRules('en-US');
console.log(prEn.select(0)); // "other" (for "0 items")
console.log(prEn.select(1)); // "one" (for "1 item")
console.log(prEn.select(2)); // "other" (for "2 items")
const prAr = new Intl.PluralRules('ar-EG');
console.log(prAr.select(0)); // "zero"
console.log(prAr.select(1)); // "one"
console.log(prAr.select(2)); // "two"
console.log(prAr.select(10)); // "few"
console.log(prAr.select(100)); // "other"
Cette API ne pluralise pas directement, mais elle fournit la classification essentielle nécessaire pour sélectionner la chaîne de traduction correcte dans vos faisceaux de messages. Par exemple, si vous avez des clés de message comme item.one
, item.other
vous utiliseriez pr.select(count)
pour choisir le bon.
6. Intl.DisplayNames
: Noms localisés pour tout
Besoin d’afficher le nom d’une langue, d’une région ou d’un script dans la langue préférée de l’utilisateur? Intl.DisplayNames
est votre solution complète.
// Display language names in English
const langNamesEn = new Intl.DisplayNames(['en'], { type: 'language' });
console.log(langNamesEn.of('fr')); // "French"
console.log(langNamesEn.of('es-MX')); // "Mexican Spanish"
// Display language names in French
const langNamesFr = new Intl.DisplayNames(['fr'], { type: 'language' });
console.log(langNamesFr.of('en')); // "anglais"
console.log(langNamesFr.of('zh-Hans')); // "chinois (simplifié)"
// Display region names
const regionNamesEn = new Intl.DisplayNames(['en'], { type: 'region' });
console.log(regionNamesEn.of('US')); // "United States"
console.log(regionNamesEn.of('DE')); // "Germany"
// Display script names
const scriptNamesEn = new Intl.DisplayNames(['en'], { type: 'script' });
console.log(scriptNamesEn.of('Latn')); // "Latin"
console.log(scriptNamesEn.of('Arab')); // "Arabic"
Avec Intl.DisplayNames
vous évitez le codage rigide d’innombrables mappages pour les noms de langue, les régions ou les scripts, en gardant votre application robuste et maigre.
Support de navigateur
Vous vous demandez peut-être sur la compatibilité des navigateurs. La bonne nouvelle est que Intl
a un excellent soutien à travers les navigateurs modernes. Tous les principaux navigateurs (Chrome, Firefox, Safari, Edge) soutiennent pleinement la fonctionnalité principale discutée (DateTimeFormat
, NumberFormat
, ListFormat
, RelativeTimeFormat
, PluralRules
, DisplayNames
). Vous pouvez utiliser en toute confiance ces API sans polyfills pour la majorité de votre base d’utilisateurs.
Conclusion: adoptez le Web mondial avec Intl
Le Intl
L’API est une pierre angulaire du développement Web moderne pour un public mondial. Il permet aux développeurs frontaux de livrer Expériences utilisateur hautement localisées Avec un minimum d’effort, en tirant parti des capacités optimisées intégrées du navigateur.
En adoptant Intl
toi réduire les dépendances, tailles de forfaitet Améliorer les performancestout en veillant à ce que votre application respecte et s’adapte aux diverses attentes linguistiques et culturelles des utilisateurs du monde entier. Arrêtez de lutter avec la logique de mise en forme personnalisée et adoptez cet outil conforme aux normes!
Il est important de se rappeler que Intl
gère le formatage de données. Bien que incroyablement puissant, il ne résout pas tous les aspects de l’internationalisation. La traduction du contenu, le texte bidirectionnel (RTL / LTR), la typographie spécifique aux paramètres régionaux et les nuances culturelles profondes au-delà du formatage des données nécessitent toujours une attention particulière. (Je peux écrire à ce sujet à l’avenir!) Cependant, pour présenter des données dynamiques avec précision et intuitivement, Intl
est la réponse native du navigateur.
Lecture complémentaire et ressources
(GG, YK)
Source link