Seltsam, gereift, wohl ausdrucksstark und erstaunlich – JavaScript ist heute die meistgenutzte Programmiersprache. Als Sprache des Browsers – und kommt auch auf dem Server mit Node zum Einsatz – ist JavaScript überall in den heutigen Web-Stacks.
Und mit vielen plattformübergreifenden mobilen Frameworks, Desktop-Wrappern, Game Engines und sogar Internet of Things (IoT)-Frameworks ist es wirklich die Welt von JavaScript – wir leben nur darin.
Klar, du bist hier, weil du all das 🔥 nutzen und lernen willst, wie du JavaScript-Anwendungen lokalisierst, damit sie für ein globales Publikum bereit sind. Hab keine Angst: Dieser Leitfaden behandelt alles, was du wissen musst, um mit der Lokalisierung von Browser-JavaScript zu starten.
Lass uns && rollen.
🔗 Ressource » Hol dir den gesamten Code, der diesen Artikel begleitet, aus unserem GitHub-Repo.
🗒 Hinweis » Internet Explorer (IE), mit einem 2.15% globalen Marktanteil, kann als veralteter Browser betrachtet werden. Der Kürze halber lassen wir IE-spezifische Lösungen in diesem Leitfaden weg. Wenn du IE unterstützt, überprüfe, ob die integrierten JavaScript-Funktionen, die wir in diesem Artikel behandeln, Forks oder Polyfills benötigen.
Wie lokalisiere ich eine Webseite mit JavaScript?
Auch wenn es verlockend ist, einfach eine fertige Internationalisierungsbibliothek (i18n) für deine Lokalisierungsbedürfnisse zu nehmen – und das kann tatsächlich die richtige Wahl für dein Projekt sein – wirst du feststellen, dass dir für kleinere Projekte auch einfaches JavaScript völlig ausreicht. Wenn du dein eigenes erstellst, bekommst du außerdem ein schönes Kochbuch mit i18n-Techniken, die du mit jeder Bibliothek verwenden kannst, die du auswählst.
🤿 Gehe tiefer » Unser Artikel, Was ist I18n: Eine einfache Definition von Internationalisierung geht näher darauf ein, was Internationalisierung (i18n) und Lokalisierung (l10n) sind.
✋🏽 Vorsicht » Wenn du eine traditionelle MPA (Multi-Page-Anwendung) erstellst, findet ein Großteil der Lokalisierung direkt auf dem Server statt. Wir arbeiten hier nur mit der Browser-Lokalisierung. Wir haben dich serverseitig abgedeckt – mit einem Node i18n-Tutorial und einem Full-Stack-JavaScript-i18n-Leitfaden.
Okay, nehmen wir an, du hast eine Seite, die du lokalisieren willst.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- ... -->
<title>My Appy Apperson</title>
</head>
<body>
<div class="container">
<h1>My Appy Apperson</h1>
<p>Willkommen in meiner kleinen Ecke im Internet!</p>
</div>
<script src="js/scripts.js"></script>
</body>
</html>

🔗 Ressource » Du kannst den gesamten Code für die App, die wir in diesem Abschnitt bauen, aus dem vanilla-Ordner in unserem GitHub-Repo bekommen.
🔗 Ressource » Ich verwende die grundlegende Skeleton CSS-Bibliothek, falls du dich wunderst.
Das sieht gut aus, aber es ist nicht wirklich globaltauglich, oder? Der gesamte Inhalt ist komplett auf Englisch festgelegt. Lass uns hier ein bisschen grundlegende i18n machen.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- ... -->
<title>My Appy Apperson</title>
</head>
<body>
<div class="container">
<h1 data-i18n-key="app-title">My Appy Apperson</h1>
<p data-i18n-key="lead">Willkommen in meiner kleinen Ecke im Internet!</p>
</div>
<script src="js/scripts.js"></script>
</body>
</html>
Beachte die data-i18n-key Attribute, die wir oben unseren Textcontainern hinzugefügt haben. Wir können darauf zugreifen, wenn das Dokument geladen wird, und deren Text durch Übersetzungen ersetzen. Tatsächlich, lass uns genau das tun.
// Das aktive Gebietsschema
const locale = "en";
// Wir können hier so viele Sprachen haben, wie wir wollen,
// und beliebige Sprachen verwenden, die wir möchten. Wir haben Englisch
// und Arabisch als Locales hier als Beispiele.
const translations = {
// Englische Übersetzungen
"en": {
"app-title": "Meine Appy Apperson",
"lead": "Willkommen auf meiner kleinen Ecke im Internet!",
},
// Arabische Übersetzungen
"ar": {
"app-title": "تطبيقي المطبق",
"lead": "أهلاً بك في مكاني الصغير على النت.",
},
};
// Wenn der Seiteninhalt bereit ist...
document.addEventListener("DOMContentLoaded", () => {
document
// Finde alle Elemente, die das Schlüsselattribut haben
.querySelectorAll("[data-i18n-key]")
.forEach(translateElement);
});
// Ersetze den inneren Text des gegebenen HTML-Elements
// mit der Übersetzung in der aktiven Sprache,
// entsprechend dem data-i18n-key des Elements
function translateElement(element) {
const key = element.getAttribute("data-i18n-key");
const translation = translations[locale][key];
element.innerText = translation;
}
Ändere die zweite Zeile oben zu const locale = "ar"; und lade die Seite neu. Wenn das DOMContentLoaded-Ereignis ausgelöst wird, werden die arabischen Übersetzungen auf unserer Seite übernommen.

🗒 Hinweis » "en" und "ar" oben sind die ISO 639-1-Codes für Englisch und Arabisch. Normalerweise benutzt du ISO-Codes für Sprachen und Länder, wenn du lokalisierst.
Lade Übersetzungen asynchron
Wir sind mit unserer i18n-Lösung gut gestartet. Allerdings skaliert das Hinzufügen von Sprachen und Übersetzungen im Moment nicht gut. Wenn unsere App wächst, würden wir wahrscheinlich unsere Übersetzungen in separate Dateien pro Sprache aufteilen. Die Übersetzungsdatei, die der aktiven Sprache entspricht, könnte dann ohne die Kosten für das Laden der anderen Sprachen geladen werden. Wir können dies ohne zu viel Aufwand umsetzen.
Zuerst verschieben wir unsere Übersetzungen aus dem Hauptskript in JSON-Dateien, jeweils eine pro unterstützter Sprache.
{
"app-title": "Meine Appy Apperson",
"lead": "Willkommen auf meiner kleinen Ecke im Internet!"
}
{
"app-title": "تطبيقي المطبق",
"lead": "أهلاً بك في مكاني الصغير على النت."
}
Lass uns unser Skript so umarbeiten, dass wir die JSON-Dateien bei Bedarf asynchron laden.
// Die Sprache, die unsere App zuerst anzeigt
const defaultLocale = "en";
// Die aktive Sprache
let locale;
// Wird mit Übersetzungen der aktiven Sprache gefüllt
let translations = {};
// Wenn der Seiteninhalt bereit ist...
document.addEventListener("DOMContentLoaded", () => {
// Übersetze die Seite in die Standardsprache
setLocale(defaultLocale);
});
// Lade Übersetzungen für die gegebene Sprache und übersetze
// die Seite für diese Sprache
async function setLocale(newLocale) {
if (newLocale === locale) return;
const newTranslations =
await fetchTranslationsFor(newLocale);
locale = newLocale;
translations = newTranslations;
translatePage();
}
// Hole das Übersetzungs-JSON-Objekt für die gegebene
// Sprache über das Netzwerk
async function fetchTranslationsFor(newLocale) {
const response = await fetch(`/lang/${newLocale}.json`);
return await response.json();
}
// Ersetze den inneren Text jedes Elements, das ein hat
// data-i18n-key Attribut mit der entsprechenden Übersetzung
// zu seinem data-i18n-key
function translatePage() {
Dokument
.querySelectorAll("[data-i18n-key]")
.forEach(translateElement);
}
// Ersetze den inneren Text des gegebenen HTML-Elements
// mit der Übersetzung in der aktiven Sprache,
// entsprechend dem data-i18n-key des Elements
function translateElement(element) {
const key = element.getAttribute("data-i18n-key");
const translation = translations[key];
element.innerText = translation;
}
Wenn wir unsere Seite jetzt neu laden, sieht sie genau so aus wie zuvor. Allerdings haben wir unsere App unter der Haube deutlich skalierbarer und wartbarer gemacht.
🗒 Hinweis » Wir verwenden die praktische Fetch API, die in modernen Browsern integriert ist, um unsere JSON-Dateien über das Netzwerk abzurufen.
Sprachwechsler erstellen
Unsere Nutzer können unsere großartigen asynchronen Fähigkeiten bisher noch nicht nutzen. Wollen wir ein Dropdown-Menü zum Sprachwechsel für sie bauen?
Wir fügen eine Navigationsleiste hinzu und platzieren unseren Umschalter in dieser Navigationsleiste.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
<title>My Appy Apperson</title>
</head>
<body>
<div class="container">
<nav class="navbar">
<div class="container">
<ul class="navbar-list navbar-left">
<!-- Navigationslinks -->
</ul>
<div class="navbar-right">
<!-- ... -->
<select data-i18n-switcher class="locale-switcher">
<option value="en">Englisch</option>
<option value="ar">Arabisch (العربية)</option>
</select>
</div>
</div>
</nav>
<h1 data-i18n-key="app-title">Meine Appy Apperson</h1>
<p data-i18n-key="lead">Willkommen auf meiner kleinen Ecke im Internet!</p>
</div>
<script src="js/scripts.js"></script>
</body>
</html>
Ein einfaches <select> reicht hier aus. Wir können ein data-i18n-switcher Attribut verwenden, damit unser JavaScript darauf zugreifen und die von dir ausgewählte Sprache laden kann.
const defaultLocale = "en";
let locale;
// ...
// Wenn der Seiteninhalt bereit ist...
document.addEventListener("DOMContentLoaded", () => {
setLocale(defaultLocale);
bindLocaleSwitcher(defaultLocale);
});
// ...
// Immer wenn du eine neue Sprache auswählst,
// Die Übersetzungen der Sprache laden und aktualisieren
// die Seite
function bindLocaleSwitcher(initialValue) {
const switcher =
document.querySelector("[data-i18n-switcher]");
switcher.value = initialValue;
switcher.onchange = (e) => {
// Setze die Sprache auf die ausgewählte Option[value]
setLocale(e.target.value);
};
}
Mit dem onchange-Ereignishandler kannst du die Übersetzungen deiner Seite entsprechend dem Wert der ausgewählten <option> aktualisieren. Et voila. Unsere Besucher können jetzt ihre eigene Sprache auswählen.

📣 Ein großes Dankeschön an Hary Murdiono JS vom Noun Project für sein translate Icon.
Erkenn die bevorzugten Spracheinstellungen deines Browsers
Manchmal ist es eine gute Idee, die bevorzugte Sprache des Nutzers zu erraten, bevor du die Möglichkeit hast, deine eigene manuell auszuwählen. Die meisten Menschen haben ihre Browser-Benutzeroberfläche in ihrer bevorzugten Sprache eingestellt, oft in der Sprache des Betriebssystems.
Die Sprache der Browser-Oberfläche findest du im navigator-Objekt, genauer gesagt im Standardwert navigator.language (String).
Das ebenfalls standardisierte – wenn auch experimentell, während ich dies schreibe – navigator.languages Array sollte die UI-Sprache als ersten Eintrag enthalten, zusätzlich zu allen Sprachen, die du in deinen bevorzugten Spracheinstellungen deines Browsers explizit festgelegt hast.
Eine kleine Funktion, die navigator.languages abfragt, kann uns beim Erkennen der Browsersprache helfen.
/**
* Hol dir die bevorzugten Sprachen aus dem Browser
*
* @param {boolean} languageCodeOnly - wenn true, wird zurückgegeben
* ["en", "fr"] anstelle von ["en-US", "fr-FR"]
* @returns array | undefined
*/
function browserLocales(languageCodeOnly = false) {
return navigator.languages.map((locale) =>
languageCodeOnly ? locale.split("-")[0] : locale,
);
}
Stell dir vor, du hast Französisch (Kanada) und Chinesisch (Vereinfacht) in deinen Browsereinstellungen.

In diesem Fall gibt browserLocales() ["fr-CA", "zh-CN"] zurück. Wenn wir browserLocales(true) aufrufen, erhalten wir ["fr", "zh"].
Wir können jetzt diese neue Funktion verwenden, um die bevorzugten Spracheinstellungen des Nutzers zu erkennen, wenn wir unsere Seite zum ersten Mal laden.
// Die Sprache, die unsere App zuerst anzeigt
const defaultLocale = "en";
const supportedLocales = ["en", "ar"];
// ...
document.addEventListener("DOMContentLoaded", () => {
const initialLocale =
supportedOrDefault(browserLocales(true));
setLocale(initialLocale);
bindLocaleSwitcher(initialLocale);
});
// ...
function isSupported(locale) {
return supportedLocales.indexOf(locale) > -1;
}
// Hol dir die erste unterstützte Sprache aus dem gegebenen
// array oder gib unsere Standard-Sprache zurück
function supportedOrDefault(locales) {
return locales.find(isSupported) || defaultLocale;
}
// ...
function browserLocales(languageCodeOnly = false) {
return navigator.languages.map((locale) =>
languageCodeOnly ? locale.split("-")[0] : locale,
);
}
Beachte, dass wir das Konzept von supportedLocales eingeführt haben; das sind die einzigen Locales, für die wir Übersetzungen haben. Mit ihnen können wir auf unsere Standardsprache zurückgreifen, wenn keine deiner bevorzugten Sprachen in unserer unterstützten Liste enthalten ist.
Unsere App wird jetzt in die erste Sprache deiner bevorzugten Liste übersetzt, mit einem eleganten Fallback.
🤿 Tauche tiefer ein » Wir behandeln die Spracherkennung sowohl im Browser als auch auf dem Server ausführlich in Erkennung der Browsersprache mit JavaScript.
Handhabung der Schreibrichtung: von rechts nach links und Sprachen, die von rechts nach links geschrieben werden.
Arabisch, Hebräisch, Persisch, Urdu und andere Sprachen verwenden Schriften, die von rechts nach links geschrieben werden. Auch wenn es viel mehr Sprachen gibt, die von links nach rechts (LTR) geschrieben werden, ist es gut zu wissen, wie du die von rechts nach links (RTL) unterstützen kannst. Glücklicherweise wird ein Großteil der Arbeit hier vom Browser erledigt; wir müssen nur das <html dir> Attribut auf unseren Seiten setzen.
// ...
// Lade Übersetzungen für das gegebene Gebietsschema und übersetze
// die Seite für diese Sprache
async function setLocale(newLocale) {
if (newLocale === locale) return;
const newTranslations = await fetchTranslationsFor(
newLocale,
);
locale = newLocale;
translations = newTranslations;
// Setze das <html dir> Attribut
document.documentElement.dir = dir(newLocale);
// Nicht notwendig für den Richtungsfluss, aber zur Sicherheit...
document.documentElement.lang = newLocale;
translatePage();
}
// ...
function dir(locale) {
return locale === "ar" ? "rtl" : "ltr";
}
// ...
Das <html dir> Attribut kann die Werte "ltr" oder "rtl" annehmen. Wir liefern diesen Wert über eine sehr einfache dir()-Funktion und setzen das Attribut jedes Mal, wenn du die Sprache wechselst.

Wenn wir unsere Browser-Entwicklertools öffnen, können wir sehen, wie sich die <html> Attribute aktualisieren, während wir die Sprachen wechseln
Der Browser stellt das Dokument automatisch von rechts nach links dar, wenn wir <html dir="rtl"> setzen. Allerdings kann jeder unserer benutzerdefinierten Richtungsstile, z.B. margin-left:, betroffen sein. 20px erfordert einige angepasste, RTL-spezifische CSS-Regeln. Das ist im Allgemeinen nicht zu kompliziert; es liegt nur ein wenig außerhalb des Rahmens dieses Artikels.
🤿 Geh tiefer » Lies mehr über lokalisierte CSS in Wie verwende ich eine CSS-Datei für die Website-Lokalisierung?
Mit unserem neuen Code bekommen wir eine arabische Seite, die Avicenna gefallen würde!

Grundlegende Übersetzungsnachrichten
Bevor wir zu komplexeren Nachrichten übergehen, wie denen mit interpolierten Werten und Pluralformen, lass uns kurz anschauen, wie wir unsere Übersetzungsnachrichten implementiert haben.
// In unserer HTML-Seite
<h1 data-i18n-key="app-title">Meine Appy Apperson</h1>
// In unserem JavaScript
function translateElement(element) {
const key = element.getAttribute("data-i18n-key");
const translation = translations[key];
element.innerText = translation;
}
// Angesichts der Tatsache, dass wir arabische Übersetzungen aus ar.json geladen haben:
translations = {
"app-title": "تطبيقي المطبق",
};
translateElement(document.querySelector("[data-i18n-key='lead']"));
// wird gerendert als
<h1 data-i18n-key="app-title">تطبيقي المطبق</h1>
Das ist unser Übersetzungssystem – kurz gesagt.
Interpolation
Was passiert, wenn wir Werte haben, die sich zur Laufzeit ändern und in unsere Nachrichten eingefügt werden müssen? Ein häufiges Beispiel ist der Name des aktuell angemeldeten Nutzers. Wir müssen unser Übersetzungssystem aktualisieren, damit solche Fälle funktionieren.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<div class="container">
<!-- ... -->
<h1 data-i18n-key="app-title">Meine Appy Apperson</h1>
<p
data-i18n-key="lead"
data-i18n-opt='{"username": "Swoodesh"}'
>
Willkommen in meiner kleinen Ecke im Netz, {username}!
</p>
</div>
<script src="js/scripts.js"></script>
</body>
</html>
Wir kennzeichnen Platzhalter für Werte, die wir in unseren Nachrichten interpolieren möchten, mit der {variable} Syntax. Ein neues data-i18n-opt Attribut speichert Schlüssel-Wert-Paare für die Interpolation in einem gültigen JSON-Objekt.
Natürlich benötigen wir die Platzhalter in unseren Sprachdateien.
{
"lead": "Willkommen in meiner kleinen Ecke des Internets, {username}!"
}
{
"lead": "أهلاً بك في مكاني الصغير على النت يا {username}.",
}
Jetzt können wir unsere translateElement-Funktion modifizieren, um Interpolationen zu verarbeiten.
// ...
function translateElement(element) {
const key = element.getAttribute("data-i18n-key");
const translation = translations[key];
const options = JSON.parse(
element.getAttribute("data-i18n-opt")
);
element.innerText = options
? Interpolate(translation, options)
: Übersetzung;
}
// Konvertier eine Nachricht wie "Hallo, {name}" in "Hallo, Chad"
// gegeben dem Interpolationsobjekt {name: "Chad"}
function interpolate(message, interpolations) {
return Object.keys(interpolations).reduce(
(interpoliert, schlüssel) =>
interpolated.replace(
new RegExp(`{\s*${key}\s*}`, "g"),
interpolations[key],
),
Nachricht,
);
}
// ...
Wenn wir ein data-i18n-opt Attribut am Element erkennen, das an translateElement() übergeben wird, verarbeiten wir die übersetzte Nachricht mit einer neuen interpolate() Funktion, bevor wir das Element aktualisieren. Wenn du jetzt die Seite lädst, siehst du die Nachricht mit dem eingefügten Wert.


Natürlich sind statische Werte im HTML für uns von begrenztem Nutzen. Idealerweise willst du in der Lage sein, dynamisch mit JavaScript zu interpolieren. Das ist nicht so schwer zu coden.
Übersetze dynamisch nach dem Laden der Seite
Lass uns eine allgemeine Übersetzungsfunktion aus translateElement() extrahieren.
// ...
function translateElement(element) {
const key = element.getAttribute("data-i18n-key");
const options =
JSON.parse(element.getAttribute("data-i18n-opt")) || {};
element.innerText = translate(key, options);
}
function translate(key, interpolations = {}) {
return interpolate(translations[key], interpolations);
}
// ...
Wir haben einfach den Code, der das Abrufen einer Nachricht in der aktiven Sprache mit Interpolationen übernimmt, in eine neue translate()-Funktion ausgelagert. Wir können diese Funktion jetzt verwenden, um die Übersetzung eines Elements nach dem Laden der Seite zu aktualisieren. Angenommen, wir möchten unseren Lead-Text aktualisieren, nachdem du dich eingeloggt hast. Kein Problem.
const element =
document.querySelector("[data-i18n-key='lead']");
// Unsere neue Funktion dient uns hier gut
element.innerText =
translate("lead", { username: "Maggie" });
// Speichere die aktualisierten Interpolationen im Dokument
// für den Fall, dass das Element in Zukunft neu gerendert wird
element.setAttribute(
"data-i18n-opt",
JSON.stringify({ username: "Maggie" }),
);

Jetzt kannst du die Übersetzungen der Elemente jederzeit aus deinem JavaScript aktualisieren.
Pluralformen
Wir müssen oft unterschiedliche Nachrichten basierend auf einem Zähler präsentieren – wie „1 Follower“ oder „20.000 Followers“ – verschiedene Sprachen haben unterschiedliche Pluralregeln. Während Englisch zwei Pluralformen hat: one und other, hat Arabisch zum Beispiel sechs Pluralformen. Historisch gesehen bedeutete dies, dass die Implementierung der Pluralformen-Unterstützung für Frontend-Apps nicht sehr einfach war. Glücklicherweise erleichtert das jetzt standardmäßige Intl.PluralRules-Objekt die Handhabung von Pluralformen.
Stell dir vor, wir sind fleißige Schreiberlinge und wollen der Welt zeigen, wie viele Artikel wir tatsächlich schon geschrieben haben.
<p
data-i18n-key="article-plural"
data-i18n-opt='{"count": 122}'
>
{count} Artikel geschrieben und es werden immer mehr.
</p>
Beachte, dass wir die Konvention verwenden, unseren Plural-Nachrichtenschlüssel mit -plural zu beenden. Und natürlich benötigen wir eine erforderliche count Ganzzahl, um die richtige Pluralform auszuwählen. Wenn wir schon von Pluralformen sprechen, lass sie uns hinzufügen.
{
// Englisch hat zwei Pluralformen
"article-plural": {
"one": "{count} Artikel und es werden immer mehr",
"other": "{count} Artikel und es werden immer mehr"
}
}
{
// Arabisch hat sechs Pluralformen
"artikel-plural": {
"zero": "لا توجد مقالات",
"one": "مقال {count}",
"two": "مقالان",
"few": "{count} مقالات",
"many": "{count} مقال",
"other": "{count} مقال"
}
}
Lass uns jetzt unsere translate-Funktion aktualisieren, damit sie Pluralnachrichten verarbeiten kann.
// ...
function translate(key, interpolations = {}) {
const message = translations[key];
if (key.endsWith("-plural")) {
return interpolate(
pluralFormFor(message, interpolations.count),
interpolations,
);
}
return interpolate(message, interpolations);
}
// ...
/*
Angenommen, es gibt ein forms-Objekt wie
{
"zero": "Keine Artikel"
"one": "Ein Artikel",
"other": "{count} Artikel"
} und eine Anzahl von 3 ergibt "3 Artikel"
*/
function pluralFormFor(forms, count) {
const matchingForm = new Intl.PluralRules(locale).select(count);
return forms[matchingForm];
}
// ...
Die magische Sauce hier ist der Teil, der new Intl.PluralRules(locale).select(...) ausführt. Das eingebaute Intl.PluralRules-Objekt kennt die Pluralregeln des jeweiligen Gebietsschemas, wenn ein Gebietsschema angegeben wird. Zum Beispiel, wenn "ar" an den Konstruktor übergeben wird und dann select(5) auf dem zurückgegebenen Objekt aufgerufen wird, gibt es "few" zurück—die korrekte Form hier.
Mit nur wenigen Zeilen Code hast du nun eine vollständig globalisierte Pluralunterstützung 🙌

Zahlenformatierung
Dreihunderttausend Euro sind „€300.000,00“ auf Englisch (Vereinigte Staaten), „300.000,00 €“ auf Deutsch (Deutschland), „€3,00,000.00“ auf Hindi (Indien)—beachte die Kommas in letzterem—und „٣٠٠٬٠٠٠٫٠٠ €“ auf Arabisch (Ägypten). Wie gehen wir mit all diesen Formaten um? Keine Sorge; ein weiteres Intl-Objekt, das Teil des modernen JavaScript-Standards ist, ist genau das Richtige. Intl.NumberFormat kommt zur Rettung!
Stell dir vor, wir sind angehende Unternehmer und wollen eine NFT-Tracking-Website mit Zahlen starten – klar, oder?
<p
data-i18n-key="nyan-cat-price"
data-i18n-opt='{"price": {"number" : 5300}}'
>
Nyan Cat (offiziell) NFT: {price}
</p>
Unser data-i18n-opt identifiziert den Zahlenwert des {price} in unseren Locale-Dateien. Wir suchen gleich nach dem number-Schlüssel, wenn wir unseren Interpolationscode aktualisieren. Zuerst lass uns unsere Nachrichtenübersetzungen bereitstellen.
{
"nyan-cat-price": "Nyan Cat (Offiziell) NFT: {price}"
}
{
"nyan-cat-price": "نيان كات NFT: {price}"
}
OK, lass uns unser JavaScript aktualisieren, damit es funktioniert.
// ...
const fullyQualifiedLocaleDefaults = {
en: "en-US",
ar: "ar-EG",
};
// ...
function interpolate(message, interpolations) {
return Object.keys(interpolations).reduce(
(interpolated, key) => {
const value = formatNumber(interpolations[key]);
return interpolated.replace(
new RegExp(`{\s*${key}\s*}`, "g"),
value,
);
},
message,
);
}
/*
Angenommen, es gibt ein Wertobjekt wie
{
"number" : 300000,
"style": "currency",
"currency": "EUR"
} und dass das aktive Gebietsschema "en" ist, gibt "€300,000.00" zurück
*/
function formatNumber(value) {
if (typeof value === "object" && value.number) {
const { number, ...options } = value;
return new Intl.NumberFormat(
fullyQualifiedLocaleDefaults[locale],
options,
).format(number);
} else {
return value;
}
}
// ...
Wenn wir unsere übersetzten Nachrichten interpolieren, geben wir den Wert, den wir einfügen, zunächst durch einen Zahlenformatierer, der wiederum das eingebaute Intl.NumberFormat Objekt verwendet. Also, mit sehr wenigen Codezeilen haben wir die Zahlenformatierung lokalisiert.


✋🏽 Hinweis » Am besten gibst du ein vollständig qualifiziertes Gebietsschema wie "en-US" an den Intl.NumberFormat()-Konstruktor weiter. Wenn wir nur einen Sprachcode übergeben, wie "en", entscheidet jeder Browser, welche Region verwendet wird, um die Zahlen zu formatieren: Ein Browser könnte standardmäßig "en-US" verwenden, während ein anderer "en-UK" wählt. Deshalb verwenden wir eine fullyQualifiedLocaleDefaults-Map in unserer formatNumber() Funktion, um eine einheitliche plattformübergreifende Formatierung zu erhalten.
Da wir alle Optionen, die in unserem Interpolationsobjekt definiert sind, an den Intl.NumberFormat() Konstruktor übergeben, können wir jederzeit seine zahlreichen Formatierungsoptionen nutzen.
<p
data-i18n-key="nyan-cat-price"
data-i18n-opt='{"price": {
"number" : 5300,
"style": "currency",
"currency": "EUR"
}}'
>
Nyan Cat (offiziell) NFT: {price}
</p>


🔗 Ressource » Du könntest unseren Kurzleitfaden zur Zahlenlokalisierung mögen.
Datumsformatierung
Ähnlich wie bei Zahlen ist die Datumsformatierung regional unterschiedlich. Der 5. Dezember 2021 wird in seiner Kurzform als „12/5/2021“ auf Englisch (US) und als „5.12.2021“ auf Deutsch (Deutschland) formatiert, zum Beispiel. Und wieder kann ein praktisches integriertes Intl.DateTimeFormat-Objekt die schwere Arbeit bei der Datumsformatierung übernehmen.
Angenommen, wir möchten das Veröffentlichungsdatum und die Uhrzeit eines unserer Artikel anzeigen.
<p
data-i18n-key="publish-date"
data-i18n-opt='{"publishDate": {
"date": "2021-12-05 15:29:00"
}}'
>
Veröffentlicht am {publishDate}
</p>
Der spezielle date Schlüssel in unserem data-i18n-opt Objekt enthält den Datums- und Uhrzeitwert, den wir formatieren möchten. Fügen wir wie gewohnt unsere lokalisierten Nachrichten hinzu.
{
// ...
"publish-date": "Veröffentlicht {publishDate}"
}
{
//...
"publish-date": "Veröffentlicht am {publishDate}"
}
Jetzt aktualisieren wir unser Übersetzungssystem, um nach date Schlüsseln zu suchen und deren Werte als lokalisierte Daten zu formatieren.
// ...
function interpolate(message, interpolations) {
return Object.keys(interpolations).reduce(
(interpolated, key) => {
const value = formatDate(
formatNumber(interpolations[key]),
);
return interpolated.replace(
new RegExp(`{\s*${key}\s*}`, "g"),
value,
);
},
Nachricht,
);
}
// ...
/*
Angenommen, es gibt ein Wertobjekt wie
{
Datum: "2021-12-05 15:29:00",
"dateStyle": "long",
"timeStyle": "short"
} und dass das aktuelle Gebietsschema 'en' ist,
gibt "5. Dezember 2021 um 15:29 Uhr" zurück
*/
function formatDate(value) {
if (typeof value === "object" && value.date) {
const { date, ...options } = value;
const parsedDate =
typeof date === "string" ? Date.parse(date) : date;
return new Intl.DateTimeFormat(
fullyQualifiedLocaleDefaults[locale],
options,
).format(parsedDate);
} else {
return value;
}
}
// ...
Nachdem wir unser Wertobjekt an unseren Zahlen-Formatter übergeben haben, verwenden wir erneut unseren neuen Datums-Formatter. Die Datumsformatierungsoptionen werden an den Intl.DateTimeFormat-Konstruktor übergeben, was eine ziemlich große Flexibilität beim Formatieren von Datumswerten ermöglicht.
✋🏽 Vorsicht » Wir verwenden oben Date.parse(), um sicherzustellen, dass unsere Zeichenfolge date in ein Date-Objekt umgewandelt wird, sonst gibt Intl.DateTimeFormat einen Fehler aus.
Damit haben wir die lokalisierte Datumsformatierung 👍
<p
data-i18n-key="publish-date"
data-i18n-opt='{"publishDate": {
"date": "2021-12-05 15:29:00",
"dateStyle": "long",
"timeStyle": "short"
}}'
>
Veröffentlicht am {publishDate}
</p>


🤿 Gehe tiefer » Wenn du nach robusteren Datumsformatierungsfunktionen suchst, schau dir unsere Übersicht an, Was ist die beste JavaScript-Datums- und Zeitbibliothek? Und unser Menschlich lesbare Anzeige von Daten in TypeScript/JavaScript bietet dir Formatierungen wie „vor 1 Stunde“.
🔗 Ressource » Wenn du ein deklaratives Framework wie React verwendest, kannst du das, was wir in diesem Abschnitt erstellt haben, weiterführen und Eigene JavaScript-i18n-Bibliothek mit TypeScript entwickeln.
Welche guten JavaScript-i18n-Bibliotheken kannst du verwenden?
Wir haben oben gezeigt, wie du deine eigene JavaScript-i18n-Bibliothek erstellst. Es könnte jedoch sinnvoller sein, für dein Projekt eine fertige i18n-Bibliothek zu übernehmen. Hier gibt es keinen Mangel an Optionen, und in diesem Artikel schauen wir uns die Bibliotheken Polyglot, i18next und Globalize genauer an.
Für eine noch größere Auswahl helfen dir unsere beliebten Artikel, den richtigen Einstieg zu finden:
🗒 Hinweis » Wenn du mit legacy gettext arbeitest, schau dir die Jed library an.
Wie lokalisiere ich eine Webseite mit Polyglot?
Polyglot ist eine kleine i18n-Bibliothek, die von Airbnb gepflegt wird und einige Lokalisierungsprobleme löst, die zuvor von JavaScripts Standardbibliotheken nicht unterstützt wurden. Am bemerkenswertesten unter den Funktionen von Polyglot ist die hervorragende Handhabung der Mehrzahl. Wie wir schon gesagt haben, wird der jetzt eingebaute Intl.PluralRules-Konstruktor von allen modernen Browsern unterstützt und löst das Pluralisierungsproblem ganz einfach. Dennoch wurde in der letzten Version dieses Artikels Polyglot stark behandelt, also wollten wir diesen Abschnitt einfügen, falls einige von euch immer noch einen Polyglot-Leitfaden wollen.
🗒 Hinweis » Es sei denn, dein Anwendungsfall erfordert Polyglot, schau dir die alternative i18next im nächsten Abschnitt an, bevor du eine Lokalisierungslösung wählst.
Ohne weitere Umschweife lass uns unsere kleine Demo-App mit Airbnbs Lokalisierungsbibliothek lokalisieren.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<div class="container">
<nav class="navbar">
<div class="container">
<ul class="navbar-list navbar-start">
<li class="navbar-item">
<a href="#" data-i18n-key="home" class="navbar-link">
Startseite
</a>
</li>
<li class="navbar-item">
<a href="#" data-i18n-key="about" class="navbar-link">
Über uns
</a>
</li>
</ul>
<div class="navbar-end">
<img src="img/translation-icon@2x.png" class="translation-icon" />
<select data-i18n-switcher class="locale-switcher">
<option value="en">Englisch</option>
<option value="ar">Arabisch (العربية)</option>
</select>
</div>
</div>
</nav>
<h1 data-i18n-key="app-title">Mit Polyglot</h1>
<p data-i18n-key="lead" data-i18n-opt='{"username": "Cadence"}'>
Willkommen in meiner kleinen Ecke im Netz, %{username}!
</p>
<p
data-i18n-key="article-plural"
data-i18n-opt='{"smart_count": 2}'
>
%{smart_count} Artikel geschrieben und es werden immer mehr.
</p>
</div>
</body>
</html>

Alles klar, lass uns dieses Ding mit Polyglot lokalisieren.
Installation
Polyglot hat einige NPM-Abhängigkeiten, also brauchst du Node lokal installiert. Mit Node kannst du eine package.json-Datei für deine Demo-App erstellen, indem du Folgendes in der Kommandozeile ausführst.
npm init -y
Um unsere NPM-Abhängigkeiten in eine Datei zu bündeln, die Browser lesen können, installieren wir den Webpack Modulbundler als Entwicklungsabhängigkeit. Der Webpack-Entwicklungsserver hilft dir beim Hot-Reload deines Bundles im Browser, während du entwickelst.
npm install --save-dev webpack webpack-cli webpack-dev-server
Alles klar, jetzt installiere den Star der Show: Polyglot.
npm install node-polyglot
Eine index.js wird als Einstiegspunkt für unsere App dienen, und wir können sie verwenden, um einen Smoke-Test der Bibliotheksinstallationen durchzuführen.
import Polyglot from "node-polyglot";
console.log({ Polyglot });
Ein start-Skript in unserer package.json wird unsere Entwicklung erleichtern, indem es den Entwicklungsserver mit unserer individuellen Konfiguration startet.
{
"name": "polyglot-demo",
// ...
"scripts": {
"start": "webpack-dev-server --config webpack.config.js"
},
// ...
"devDependencies": {
"webpack": "^5.65.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.6.0"
},
"dependencies": {
"node-polyglot": "^2.4.2"
}
}
🗒 Hinweis » Wir verwenden eine relativ einfache webpack.config.js, um unsere App zu bündeln und den Entwicklungsserver zu konfigurieren. Schau dir unser Git-Repository auf GitHub an.
Jetzt bringen wir unser gebündeltes JS direkt vor dem schließenden </body>-Tag in unserer public/index.html-Datei ein.
<script src="./bundle.js"></script>
Damit kannst du jetzt das start-Skript im Terminal ausführen, um den Webpack-Dev-Server zu starten.
npm start
Wenn alles gut läuft, öffnet sich unsere App automatisch im Browser. Wenn wir unsere Browser-Entwicklertools öffnen, sollten wir Konsolenprotokolle sehen, die in etwa wie die folgenden aussehen.

Grundlegende Übersetzungen
Schauen wir uns die grundlegende Nutzung von Polyglot an. Hier ist das Rezept:
// 1. Importiere die Bibliothek
import Polyglot from "node-polyglot";
// 2. Erstelle eine Instanz
const polyglot = new Polyglot();
// 3. Füge Übersetzungsnachrichten für das aktive Gebietsschema hinzu
polyglot.extend({
"app-title": "Mit Polyglot",
});
// 4. Verwende die Texte, um Seitenelemente zu übersetzen
const element = document.querySelector(
"[data-i18n-key='app-title']",
);
// polyglot.t() gibt eine Übersetzungsnachricht zurück, die angegeben wurde
// ein Schlüssel
element.innerHTML = polyglot.t("app-title");
Um die Sprache zu wechseln, kannst du die Seite mit den neuen Spracheinstellungen neu laden.
✋🏽 Hinweis » Wir verwenden innerHTML in diesem Artikel, um den Inhalt eines Elements festzulegen. Sei vorsichtig mit diesem Attribut in der Produktion; stelle sicher, dass du jegliches HTML, das du mit innerHTML einfügst, bereinigst, um XSS-(Cross-Site-Scripting-)Angriffe zu vermeiden.
import Polyglot from "node-polyglot";
const polyglot = new Polyglot();
polyglot.extend({
"app-title": "مع بوليجلوت",
});
const element = document.querySelector(
"[data-i18n-key='app-title']",
);
element.innerHTML = polyglot.t("app-title");
Asynchrones Laden der Übersetzungsdatei
Während das oben für die kleinsten Apps gut funktioniert, könnten wir es noch besser machen, indem wir unsere Übersetzungsdateien in separate JSON-Dateien pro Locale aufteilen.
{
"app-title": "Mit Polyglot",
"home": "Home",
"about": "Über"
}
{
"app-title": "مع بوليجلوت",
"home": "الرئيسية",
"about": "Über uns",
}
Jetzt kannst du eine Standardsprache für deine App konfigurieren und ihre Übersetzungen aus dem Netzwerk laden, wenn deine Seite geladen wird.
import Polyglot from "node-polyglot";
const defaultLocale = "en";
const polyglot = new Polyglot();
// Lade Übersetzungen aus dem Netzwerk
async function loadTranslations(locale) {
return await fetch(`/lang/${locale}.json`).then(
(response) => response.json(),
);
}
// Übersetze alle Elemente auf der Seite, die unser benutzerdefiniertes Attribut haben
// data-i18n-key-Attribut
function translatePage() {
const translatableElements = document.querySelectorAll(
"[data-i18n-key]",
);
translatableElements.forEach((el) => {
const key = el.getAttribute("data-i18n-key");
el.innerHTML = polyglot.t(key);
});
}
// Init
(async function () {
const translations = await loadTranslations(
defaultLocale,
);
polyglot.extend(translations);
translatePage();
})();
Damit erhalten wir die folgende Darstellung im Browser.

Unsere Navigationsmenüpunkte und der Haupttitel sind in unsere Standardsprache Englisch übersetzt. Beachte jedoch die Polyglot-Fehler in der Konsole und wie fehlende Schlüssel (lead und article-plural) den Wert der Schlüssel selbst anzeigen. Wir fügen gleich Übersetzungen für diese Schlüssel hinzu, um das zu beheben.
Wenn wir defaultLocale in "ar" ändern, erhalten wir folgende Darstellung.

Sprachumschalter
Unsere App ist jetzt skalierbarer, da nur die Übersetzungen der aktiven Sprache geladen werden. Lass uns das nutzen, um einen Sprachumschalter zu bauen. Wir haben bereits das HTML für den Switcher in unserer App:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<div class="container">
<nav class="navbar">
<div class="container">
<!-- ... -->
<div class="navbar-end">
<img src="img/translation-icon@2x.png" class="translation-icon" />
<select data-i18n-switcher class="locale-switcher">
<option value="en">Englisch</option>
<option value="ar">Arabisch (العربية)</option>
</select>
</div>
</div>
</nav>
<!-- ... -->
<script src="./bundle.js"></script>
</body>
</html>
Das Einbinden dieses <select>-Elements aus unserem JavaScript ermöglicht es uns, unsere Sprachwechsel-Funktion hinzuzufügen.
import Polyglot from "node-polyglot";
const defaultLocale = "en";
const polyglot = new Polyglot();
// ...
// Lade Übersetzungen für das angegebene Gebietsschema und übersetze
// Seitenelemente für diese Sprache
async function loadAndTranslate(locale) {
const translations = await loadTranslations(locale);
polyglot.replace(translations);
translatePage();
}
// Jedes Mal, wenn der Nutzer die aktive Sprache wechselt, laden
// die Nachrichten dieses Gebietsschemas in die Seite
function bindLocaleSwitcher(initialValue) {
const switcher = document.querySelector(
"[data-i18n-switcher]",
);
switcher.value = initialValue;
switcher.onchange = (e) => {
loadAndTranslate(e.target.value);
};
}
// Init
loadAndTranslate(defaultLocale);
bindLocaleSwitcher(defaultLocale);
Wir haben den Code, der unsere Übersetzungsnachrichten lädt und unsere Seiteninhalte übersetzt, in eine wiederverwendbare loadAndTranslate()<1>-Funktion umstrukturiert. Eine neue Funktion bindLocaleSwitcher() verbindet sich mit dem Sprachwechsler <select>; sie nutzt loadAndTranslate(), um die Übersetzungen basierend auf der von dir gewählten Sprache zu aktualisieren.
✋🏽 Heads up » polyglot.extend() wird Übersetzungsnachrichten zu den bereits geladenen hinzufügen, daher verwenden wir polyglot.replace(), um sicherzustellen, dass wir nur die Übersetzungen der aktiven Sprache laden.
Das sollte unseren schicken Sprachwechsler zum Laufen bringen.

Interpolation
Unser Haupttext enthält den Namen des aktuell angemeldeten Nutzers (natürlich gemockt). Diese Art von interpoliertem Wert wird von Polyglot standardmäßig mit einer speziellen %{variable} Syntax behandelt.
🗒 Hinweis » Du kannst die Zeichen, die interpolierte Werte kennzeichnen, mit der interpolation Option, die an den Polyglot-Konstruktor übergeben wird, ändern.
<!-- ... -->
<p data-i18n-key="lead" data-i18n-opt='{"username": "Cadence"}'>
Willkommen in meiner kleinen Ecke im Netz, %{username}!
</p>
<!-- ... -->
{
// ...
"lead": Willkommen in meiner kleinen Ecke im Netz, %{username}!
}
{
// ...
"lead": "أهلاً بك في مكاني الصغير على النت يا %{username}."
}
Ein paar Zeilen Code können zu unserer Funktion translatePage() hinzugefügt werden, um Interpolationen zu berücksichtigen.
// ...
// Übersetze alle Elemente auf der Seite, die ein ... haben
// data-i18n-key-Attribut
function translatePage() {
const translatableElements = document.querySelectorAll(
"[data-i18n-key]",
);
translatableElements.forEach((el) => {
const key = el.getAttribute("data-i18n-key");
// Extrahiere Interpolationsschlüssel/Werte aus dem HTML und
// in JSON umwandeln
const interpolations = el.getAttribute("data-i18n-opt");
const parsedInterpolations = interpolations
? JSON.parse(interpolations)
: {};
// Übergebe die analysierten Interpolationen an polyglot.t(),
// die automatisch Ersetzungen behandelt
el.innerHTML = polyglot.t(key, parsedInterpolations);
});
}
// ...
Mit dem obigen Code haben wir nun unseren interpolierten Einleitungsabsatz in der aktiven Sprache gerendert.


Plural
Angenommen, wir möchten dir als aktuell angemeldetem Nutzer zeigen, wie viele Nachrichten du erhalten hast: „Du hast 1 neue Nachricht“ oder „Du hast 12 neue Nachrichten“, zum Beispiel. Polyglot behandelt Pluralformen auf diese Weise gut. Wir müssen nur unsere Übersetzungen mit dem speziellen interpolierten Zahlenwert, smart_count, hinzufügen.
<!-- ... -->
<p
data-i18n-key="new-messages"
data-i18n-opt='{"smart_count": 12}'
>
Du hast %{smart_count} neue Nachrichten
</p>
<!-- ... -->
Polyglot verwendet smart_count, um je nach aktueller Sprache die korrekte Pluralform aus einer Übersetzungsnachricht auszuwählen. Pluralformen werden in unseren Nachrichten mit vier senkrechten Strichen |||| getrennt. Englisch hat one und other Pluralformen, und wir müssen sie in der Reihenfolge bereitstellen:
{
// ...
"new-messages": "Du hast %{smart_count} neue Nachricht |||| Du hast %{smart_count} neue Nachrichten"
}
Arabisch hat sechs Pluralformen und wir fügen sie unseren Nachrichten auf die gleiche Weise hinzu.
{
// ...
"new-messages": "Du hast keine neuen Nachrichten |||| Du hast eine neue Nachricht |||| Du hast zwei neue Nachrichten |||| Du hast %{smart_count} neue Nachrichten |||| Du hast %{smart_count} neue Nachricht |||| Du hast %{smart_count} neue Nachricht"
}
🗒 Hinweis » Schau dir den Abschnitt Wie lokalisiere ich eine Webseite mit JavaScript? ➞ Pluralformen an, um mehr über Pluralformen zu erfahren.
Eine weitere Sache: Standardmäßig ist Polyglot völlig ahnungslos über das aktive Gebietsschema, daher kennt es die Pluralregeln des aktiven Gebietsschemas nicht, es sei denn, wir geben das Gebietsschema beim Laden ausdrücklich an.
// ...
// Lade Übersetzungen für das angegebene Gebietsschema und übersetze
// Seitenelemente für diese Sprache
async function loadAndTranslate(locale) {
const translations = await loadTranslations(locale);
polyglot.locale(locale);
polyglot.replace(translations);
translatePage();
}
// ...
Das war's! Wir unterstützen jetzt fortschrittliche Pluralformen in unserer App.


🔗 Ressource » Hol dir den gesamten Code für unsere Polyglot-App von unserem GitHub-Repo.
🔗 Ressource » Die offizielle Polyglot-Dokumentation ist genauso kompakt wie die Bibliothek selbst.
Wie lokalisiere ich eine Webseite mit i18next?
Während ich dies schreibe, ist i18next eine der beliebtesten JavaScript-i18n-Bibliotheken. Die „einmal lernen, überall [verwenden]“ Bibliothek funktioniert eigenständig und mit einer Vielzahl von JavaScript-Frameworks. Ein reichhaltiges Plugin-Ökosystem bedeutet, dass du oft nur eine NPM-Installation von der Lösung eines häufigen i18n-Problems entfernt bist. Das alles macht i18next zu einer einfachen Empfehlung.
Alles klar, genug Geschwafel. Lass uns unser kleines Demo noch einmal anschauen und es mit i18next lokalisieren.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<div class="container">
<nav class="navbar">
<div class="container">
<ul class="navbar-list navbar-start">
<li class="navbar-item">
<a href="#" data-i18n-key="home" class="navbar-link">
Startseite
</a>
</li>
<li class="navbar-item">
<a href="#" data-i18n-key="about" class="navbar-link">
Über
</a>
</li>
</ul>
<div class="navbar-end">
<img src="img/translation-icon@2x.png" class="translation-icon" />
<select data-i18n-switcher class="locale-switcher">
<option value="en">Englisch</option>
<option value="ar">Arabisch (العربية)</option>
</select>
</div>
</div>
</nav>
<h1 data-i18n-key="app-title">Mit i18next</h1>
<p data-i18n-key="lead" data-i18n-opt='{"username": "Zelda"}'>
Willkommen in meiner kleinen Ecke im Netz, {{username}}!
</p>
<p data-i18n-key="new-messages" data-i18n-opt='{"count": 12}'>
Du hast {{count}} neue Nachrichten
</p>
</div>
<script src="./bundle.js"></script>
</body>
</html>
Hier gibt es nicht viel Neues. Lass uns mit der Lokalisierung beginnen.
Installation
Wir verwenden Node und seinen NPM Paket-Manager, um i18next zu installieren. Zuerst, erstellen wir die Datei package.json, um unsere Projektabhängigkeiten und NPM-Skripte zu verfolgen, indem wir Folgendes in der Kommandozeile ausführen.
npm init -y
Der Webpack-Bundler ermöglicht es uns, i18next, seine Plugins und unser eigenes JavaScript zu bündeln und in einer Datei im Browser bereitzustellen. Lass uns Webpack samt Entwicklungsserver installieren, der eine praktische Hot-Reload-Funktion hat, die die Entwicklung erleichtert:
npm install --save-dev webpack webpack-cli webpack-dev-server
Vergiss unsere i18n-Bibliothek natürlich nicht:
npm install i18next
Ein praktisches npm start-Skript kann das Starten unseres Entwicklungsservers abkürzen.
{
"name": "i18next-demo",
//...
"scripts": {
"start": "webpack-dev-server --config webpack.config.js"
},
// ...
"devDependencies": {
"webpack": "^5.65.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.6.0"
},
"dependencies": {
"i18next": "^21.6.3"
}
}
🗒 Hinweis » Wir verwenden eine relativ einfache webpack.config.js-Datei, um unsere App zu bündeln und den Dev-Server zu konfigurieren. Schau es dir in unserem Git-Repo auf GitHub an.
Lass uns einen index.js Einstiegspunkt für unsere App erstellen und i18next einem kurzen Test unterziehen, um zu prüfen, ob es richtig installiert ist.
import i18next from "i18next";
console.log({ i18next });
Wenn du npm start in der Befehlszeile ausführst, startet der Webpack-Dev-Server und lädt deine App automatisch im Browser.

Grundlegende Übersetzungsnachrichten
i18next ist flexibel darin, wie Übersetzungsnachrichten angenommen werden. Das meiste konfigurieren wir, während wir die Bibliothek mit i18next.init(...) initialisieren. Wir fügen unsere Übersetzungsnachrichten direkt unter der Option resources ein.
import i18next from "i18next";
i18next.init({
// Das aktive Gebietsschema
lng: "en",
// Aktiviert nützliche Konsolenausgaben während der Entwicklung
debug: true,
// Übersetzungsnachrichten, nach Locale-Code zugeordnet
Ressourcen: {
en: {
// Standardmäßig erwartet i18next Nachrichten unter dem
// "translation" namespace
translation: {
"app-title": "Mit Polyglot",
home: "Home"
about: "Über",
},
},
ar: {
translation: {
"app-title": "مع بوليجلوت",
"home": "الرئيسية",
"about": "نبذة عنا",
},
},
},
});
// Seitenelemente übersetzen
const translatableElements = document.querySelectorAll(
"[data-i18n-key]",
);
translatableElements.forEach((el) => {
const key = el.getAttribute("data-i18n-key");
el.innerHTML = i18next.t(key);
});
Damit sollten wir beim Neuladen unserer App im Browser keine Änderungen sehen. Wenn du jedoch lng in "ar" änderst, siehst du die folgenden arabischen Übersetzungen.

🗒 Hinweis » Die debug: true-Option aktiviert sehr nützliche Konsolenprotokolle im Browser. Beachte die oben fehlenden Schlüsselbotschaften, zum Beispiel.
Asynchrone Übersetzungsladefunktion
Zukunftsorientierte Entwickler, die wir sind, lass uns unsere App skalierbarer machen, indem wir unsere Übersetzungen in separate Dateien aufteilen – eine pro Locale.
{
"app-title": "Mit i18next"
"home": "Home",
"about": "Über"
}
{
"app-title": "مع آي أيتين نيكست",
"home": "الرئيسية",
"about": "نبذة عنا",
}
i18next ist ausgereift und hat viele Grundlagen abgedeckt. Deshalb müssen wir keinen eigenen Code schreiben, um Übersetzungsdateien aus dem Netzwerk zu laden. Das offizielle HTTP-Backend wird in die Bibliothek integriert und erledigt die gesamte Arbeit für uns. Installier es.
npm install i18next-http-backend
Wir können jetzt das Backend in unsere index.js einbinden und nutzen(), während wir i18next initialisieren.
import i18next from "i18next";
import HttpApi from "i18next-http-backend";
// Wir machen die Funktion asynchron, damit wir await verwenden können
// auf die Übersetzungsdatei, während sie übertragen wird
// Netzwerk
async function initI18next() {
// Wir verwenden() das Backend und warten, bis es geladen ist.
// Übersetzungen aus dem Netzwerk
await i18next.use(HttpApi).init({
lng: "en",
debug: true,
// Entferne die eingebetteten `Ressourcen`
// Laden der Entwicklungssprache deaktivieren
fallbackLng: false,
// Http-Backend konfigurieren
backend: {
loadPath: "/lang/{{lng}}.json",
},
});
}
// Schnelle Umstrukturierung des Seitenübersetzungscodes
// zu einer Funktion
function translatePageElements() {
const translatableElements = document.querySelectorAll(
"[data-i18n-key]",
);
translatableElements.forEach((el) => {
const key = el.getAttribute("data-i18n-key");
el.innerHTML = i18next.t(key);
});
}
// Initialisierung
(async function () {
await initI18next();
translatePageElements();
})();
Die Option backend.loadPath überschreibt den Standardpfad der Übersetzungsdatei des Backends. Ein spezieller {{lng}} Platzhalter wird durch das aktive Gebietsschema ersetzt. Zum Beispiel, wenn unsere App zum ersten Mal geladen wird, sucht das Backend nach /lang/en.json, da wir die Standardsprache in unserer Konfiguration zuvor als en festgelegt haben.
Das war’s auch schon. Unsere Übersetzungen werden jetzt aus dem Netzwerk geladen, anstatt in unserem Code eingebettet zu werden.
Unterstützte Sprachversionen und Fallback-Option
Oft möchten wir eine Liste von Locales angeben, die unsere App unterstützt, sowie ein Locale, auf das zurückgegriffen wird, wenn eine Übersetzung fehlt. Du kannst die Konfigurationsoptionen supportLngs und fallbackLng von i18next verwenden, um das zu erreichen.
// ...
async function initI18next() {
await i18next.use(HttpApi).init({
lng: "en",
debug: true,
supportedLngs: ["en", "ar"],
fallbackLng: "en",
backend: {
loadPath: "/lang/{{lng}}.json",
},
});
}
// ...
✋🏽 Heads up » Das Fallback-Gebietsschema wird immer geladen, unabhängig vom aktiven Gebietsschema.
Automatische Erkennung deiner Sprache und Region
Es ist üblich, die Browsereinstellungen der Nutzer:innen zu erkennen und deren Spracheinstellung zu verwenden, wenn wir sie unterstützen. Das ist normalerweise etwas knifflig, aber i18next hat ein offizielles Plugin, das uns hier schnell weiterhilft. Lass uns damit anfangen, es zu installieren.
npm install i18next-browser-languagedetector
Ähnlich wie beim HTTP-Backend importierst du das Detektor-Plugin und verwendest() es bei der Initialisierung.
import i18next from "i18next";
import HttpApi from "i18next-http-backend";
import LanguageDetector from "i18next-browser-languagedetector";
async function initI18next() {
await i18next
.use(HttpApi)
.use(LanguageDetector)
.init({
debug: true,
supportedLngs: ["en", "ar"],
fallbackLng: "en",
// Erlaube, "en" zu verwenden für
// "en-US", "en-CA", etc.
nonExplicitSupportedLngs: true,
backend: {
loadPath: "/lang/{{lng}}.json",
},
});
}
// ...
Und das ist alles, was du brauchst, um mit i18next eine solide automatische Spracherkennung zu bekommen.
🔗 Ressource » Du fragst dich vielleicht, welche Kriterien der Locale-Detektor verwendet, um das Locale des Nutzers zu bestimmen. Wir behandeln dies ausführlich in unserem Guide to React Localization with i18next.
✋🏽 Hinweis » Die Sprach- und Regionserkennung speichert die erkannte Spracheinstellung standardmäßig im lokalen Speicher deines Browsers und verwendet diesen Wert, wenn du unsere Website erneut besuchst.
🤿 Gehe tiefer » Wir haben einen speziellen Leitfaden zur Erkennung der Browsersprache mit JavaScript, der dein Interesse wecken könnte.
Sprachumschalter
Die automatische Spracherkennung ist zwar praktisch, aber oft brauchst du eine Benutzeroberfläche, um deine bevorzugte Sprache explizit festzulegen. Wir haben bereits das Markup für einen Sprachumschalter eingerichtet.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<div class="container">
<nav class="navbar">
<div class="container">
<!-- ... -->
<div class="navbar-end">
<img src="img/translation-icon@2x.png" class="translation-icon" />
<select data-i18n-switcher class="locale-switcher">
<option value="en">Englisch</option>
<option value="ar">Arabisch (العربية)</option>
</select>
</div>
</div>
</nav>
<!-- ... -->
</div>
<script src="./bundle.js"></script>
</body>
</html>
Haken wir in dieses HTML ein und verwende die Funktion i18next.changeLanguage(), um deine aktive Sprache auf die von dir gewählte einzustellen. Nachdem die lokalen Nachrichten geladen sind, kannst du translatePageElements anhängen, um die Seite mit den aktualisierten Übersetzungen neu zu rendern.
// ...
function bindLocaleSwitcher(initialValue) {
const switcher = document.querySelector(
"[data-i18n-switcher]",
);
switcher.value = initialValue;
switcher.onchange = (e) => {
i18next
.changeLanguage(e.target.value)
.then(translatePageElements);
};
}
// Init
(async function () {
await initI18next();
translatePageElements();
bindLocaleSwitcher(i18next.resolvedLanguage);
})();
✋🏽 Hinweis » Der Lokalisierungsdetektor könnte eine Sprache erkannt haben, die wir nicht unterstützen, und dieser Wert wird in i18next.language vorhanden sein. Wir verwenden i18next.resolvedLanguage, um sicherzustellen, dass wir die aktive, unterstützte Sprache beim Initialisieren unseres Sprachumschalters verwenden.
Et voilà! Sprachwechsel-Benutzeroberfläche:

Interpolation
Standardmäßig verwendet i18next die {{variable}}-Syntax, um interpolierte Werte in Übersetzungen zu kennzeichnen.
<!-- ... -->
<p data-i18n-key="lead" data-i18n-opt='{"username": "Zelda"}'>
Willkommen in meiner kleinen Ecke im Netz, {{username}}!
</p>
<!-- ... -->
{
// ...
"lead": "Willkommen in meiner kleinen Ecke im Internet, {{username}}!"
}
{
// ...
"lead": "أهلاً بك في مكاني الصغير على النت يا {{username}}."
}
Wir können diese dynamischen Werte aus unseren HTML-Attributen abrufen und sie an i18next.t() übergeben, das die Interpolation für uns übernimmt.
// ...
Funktion translatePageElements() {
const translatableElements = document.querySelectorAll(
"[data-i18n-key]",
);
translatableElements.forEach((el) => {
const key = el.getAttribute("data-i18n-key");
const interpolations = el.getAttribute("data-i18n-opt");
const parsedInterpolations = interpolations
? JSON.parse(interpolations)
: {};
el.innerHTML = i18next.t(key, parsedInterpolations);
});
}
// ...
Damit werden unsere dynamischen Werte in unseren Nachrichten ersetzt.


Plural
Unter der Haube versucht i18next, die Standard-Intl.PluralRules zu verwenden, um Pluralformen zu verwalten. Eine spezielle interpolierte count Variable steuert die Wahl der Pluralform abhängig vom aktiven Locale.
<!-- ... -->
<p data-i18n-key="new-messages" data-i18n-opt='{"count": 12}'>
Du hast {{count}} neue Nachrichten
</p>
<!-- ... -->
i18next verwendet eine message_form Konvention für plurale Nachrichtenschlüssel. Zum Beispiel, um die one und other Formen in einer englischen new-messages Übersetzung zu behandeln, können wir Folgendes angeben.
{
// ...
"new-messages_one": "Du hast {{count}} neue Nachricht"
"new-messages_other": "Du hast {{count}} neue Nachrichten"
}
Arabisch hat sechs Pluralformen, und wir können sie auf ähnliche Weise angeben.
{
// ...
"new-messages_zero": "لا توجد لديك رسائل جديدة",
"new-messages_one": "لديك رسالة جديدة",
"new-messages_two": "لديك رسالتان جداد",
"new-messages_few": "لديك {{count}} رسائل جديدة",
"new-messages_many": "لديك {{count}} رسالة جديدة",
"new-messages_other": "لديك {{count}} رسالة جديدة"
}
Mit wenig Aufwand kann unsere App Nachrichten im Plural anzeigen.


🔗 Ressource » Hol dir den gesamten Code, den wir oben behandelt haben, aus unserem GitHub-Repo.
Wie lokalisiere ich eine React-, Angular- oder Vue-App?
In den letzten Jahren haben deklarative Frameworks wie React, Angular, Vue.js, und andere die Frontend-Web-Welt im Sturm erobert. Wir behandeln diese Frameworks ausführlich in unserem Blog. Da React das beliebteste unter den großen Frameworks ist, geben wir dir hier gleich einen kurzen Leitfaden zur Lokalisierung von React-Apps. Und für andere deklarative Frameworks, schau dir unsere folgenden ausführlichen Artikel an.
Angular-Lokalisierungsartikel
- Übersetzen von Angular-Anwendungen mit dem integrierten I18n-Modul
- Was ist die beste Angular-Bibliothek für Internationalisierung?
- Angular L10n mit I18next
- Angular 10 Tutorial zur Lokalisierung mit Transloco
- Full-Stack I18n mit Angular und .NET Core
Lokalisierungsartikel für Vue.js
- Der ultimative Vue-3-Lokalisierungsleitfaden
- Tiefgehender Einblick: Vue-Übersetzung mit vue-i18next
- Das einzige Nuxt.js-Tutorial zu I18n, das du jemals brauchen wirst (Vue-basiert)
Lokalisierungsartikel für andere Frameworks
Uns ist bewusst, dass einige unserer Leser vielleicht Svelte, Next oder ein anderes Framework verwenden. Deshalb schreiben wir immer über das Neueste und Beste. Hier ist eine Auswahl an Leitfäden, wie du die App, die du gerade in deinem Lieblings-Framework baust, lokalisieren kannst:
- So lokalisierst du eine Svelte-App mit svelte-i18n
- Ein Schritt-für-Schritt-Leitfaden zur Svelte-Lokalisierung mit svelte-i18n v3
- So lokalisierst du SolidJS-Apps mit I18next
- So lokalisierst du Mithril-Anwendungen
- So lokalisierst du Apps mit dem Aurelia-Framework
- Lokalisierung von StimulusJS-Anwendungen mit I18next
- Full-Stack JavaScript I18n Schritt für Schritt (mit Next.js und Sails.js)
🗒 Hinweis » Genauer gesagt: Wenn du mit internationalen Telefonnummern arbeitest, schau dir die libphonenumber-Bibliothek an. Es ist framework-unabhängig!
Wie lokalisiere ich eine React-App mit i18next?
Wie versprochen, werfen wir einen schnellen Blick darauf, wie du deine React-Apps mit der i18next-Bibliothek lokalisierst. Wir haben i18next bereits früher in diesem Artikel behandelt, daher konzentrieren wir uns hier auf die React-Integration.
🤿 Gehe tiefer » Ein Leitfaden zur React-Lokalisierung mit i18next deckt mehr ab und geht mehr in die Tiefe als unser kurzer Überblick hier.
Zuerst nehmen wir unsere vertraute Demo-App und zerlegen sie in React-Komponenten.
import "./App.css";
import Navbar from "./layout/Navbar";
function App() {
return (
<div className="container">
<Navbar />
<h1>React i18n</h1>
<p>
Willkommen in meinem kleinen Bereich im Internet, schön, dass du hier bist!
</p>
<p>Du hast count neue Nachrichten</p>
</div>
);
}
export default App;
import LocaleSwitcher from "../features/LocaleSwitcher";
function Navbar() {
return (
<nav className="navbar">
<div className="container">
<ul className="navbar-list navbar-start">
<li className="navbar-item">
<a href="#" className="navbar-link">
Startseite
</a>
</li>
<li className="navbar-item">
<a href="#" className="navbar-link">
Über
</a>
</li>
</ul>
<div className="navbar-end">
<LocaleSwitcher />
</div>
</div>
</nav>
);
}
export default Navbar;
function LocaleSwitcher() {
return (
<>
<img
alt="Übersetzungssymbol"
src="img/translation-icon@2x.png"
className="translation-icon"
/>
<select className="locale-switcher">
<option value="en">Englisch</option>
<option value="ar">Arabisch (العربية)</option>
</select>
</>
);
}
export default LocaleSwitcher;
Der Sprachumschalter tut momentan nicht viel, aber das ändern wir bald. Im Moment haben wir einen guten Ausgangspunkt für die Lokalisierung.

Bibliotheksinstallation
Zusätzlich zu i18next nutzen wir das offizielle react-i18next -Integrationsframework, das die Verwendung von i18next mit React zum Kinderspiel macht. Wechsle ins Projektverzeichnis und führe folgenden Befehl in der Kommandozeile aus, um die Bibliotheken zu installieren.
npm install i18next react-i18next
Als nächstes initialisieren wir i18next und verwende() die React-Integration, wie wir es machen. Der grundlegendste Weg, i18next Übersetzungen bereitzustellen, besteht darin, die resources Option bei der Initialisierung zu verwenden.
import i18next from "i18next";
import { initReactI18next } from "react-i18next";
i18next.use(initReactI18next).init({
Ressourcen: {
en: {
translation: {
"app-title": "Mit React",
},
},
ar: {
translation: {
"app-title": "مع ريأكت",
},
},
},
lng: "en",
debug: true,
Interpolation: {
escapeValue: false,
},
});
export default i18next;
🗒 Hinweis » Wir setzen die interpolation.escapeValue auf false, um die standardmäßige Escapierung, die i18next zum Schutz vor XSS-Angriffen durchführt, zu deaktivieren, da React das ohnehin für uns erledigt.
Zieh unser Modul in unser Stammverzeichnis index.js, damit wir i18next initialisieren können, wenn unsere App geladen wird.
import React from "react";
import ReactDOM from "react-dom";
import "./lib/skeleton/normalize.css";
import "./lib/skeleton/skeleton.css";
import "./services/i18n";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root"),
);
// ...
Grundübersetzungen
Die vertraute i18next.t() Übersetzungsfunktion kannst du in unseren React-Komponenten verwenden. Wir müssen nur den useTranslation React Hook importieren, damit t verfügbar ist.
import { useTranslation } from "react-i18next";
import Navbar from "./layout/Navbar";
import "./App.css";
function App() {
const { t } = useTranslation();
return (
<div className="container">
<Navbar />
<h1>{t("app-title")}</h1>
// ...
</div>
);
}
export default App;
Wenn du die App neu lädst, sieht alles genauso aus wie vorher. Wenn du jedoch den Wert lng in unserem Initialisierer src/services/i18n.js auf "ar" änderst, solltest du sehen, dass der App-Titel auf Arabisch lokalisiert wird.

Asynchrones Laden von Übersetzungsdateien
Mach unsere App skalierbarer, indem du unsere Übersetzungen in sprachspezifische Dateien aufteilst. Das praktische, offizielle i18next-http-backend Plugin macht das für uns zu einer schnellen Aufgabe. Lass es uns installieren.
npm install i18next-http-backend
Das Backend wird standardmäßig nach Dateien unter /locales/{{lng}}/{{ns}}.json suchen, wobei {{lng}} die aktive Sprache auflöst und {{ns}} den aktiven Namensraum auflöst. Da der Standardnamensraum translation ist, können wir unsere englischen Übersetzungen in public/locales/en/translation.json ablegen.
{
"app-title": "Mit React",
"home": "Home",
"about": "Über"
}
Unsere arabische Datei folgt derselben Konvention:
{
"app-title": "مع ريأكت",
"home": "الرئيسية",
"about": "Über uns",
}
Wir müssen jetzt nur noch das Backend importieren und verwenden(), wenn wir i18next initialisieren. Wir möchten auch unsere inlinierte Übersetzungen unter dem resources Schlüssel entfernen, da das Plugin jetzt unsere Übersetzungsnachrichten aus dem Netzwerk lädt.
import i18next from "i18next";
import { initReactI18next } from "react-i18next";
import HttpApi from "i18next-http-backend";
i18next
.use(initReactI18next)
.use(HttpApi)
.init({
// Entferne `resources`
lng: "en",
debug: true,
Interpolation: {
escapeValue: false,
},
});
export default i18next;
Wenn du die App neu lädst, solltest du exakt dieselbe lokalisierte Darstellung sehen. Natürlich werden die Übersetzungen der aktiven Sprache jetzt über das Netzwerk geladen, sodass deine App schneller lädt und leichter zu skalieren und zu warten ist.

Sprachumschalter
Eine Sprachwechsel-UI baust du mit React und i18next ganz einfach. Wir können unsere LocaleSwitcher-Komponente aktualisieren und das <select> darin so steuern, dass die aktive Sprache auf die von dir gewählte geändert wird.
import { useTranslation } from "react-i18next";
function LocaleSwitcher() {
const { i18n } = useTranslation();
return (
<>
<img
src="img/translation-icon@2x.png"
alt="Übersetzungssymbol"
className="translation-icon"
/>
<select
className="locale-switcher"
value={i18n.language}
onChange={(e) =>
i18n.changeLanguage(e.target.value)
}
>
<option value="en">Englisch</option>
<option value="ar">Arabisch (العربية)</option>
</select>
</>
);
}
export default LocaleSwitcher;
Die i18next React-Integration stellt sicher, dass die Übersetzungen neu gerendert werden, wenn die aktive Sprache geändert wird.

🔗 Ressource » Hol dir den Code für alles, was wir oben gebaut haben, aus unserem GitHub-Repo.
Artikel zur Lokalisierung mit React
Wir lieben es, in unserem Blog über React zu schreiben, deshalb freuen wir uns, dir eine Auswahl unserer tiefgehenden Artikel und React-basierten Framework-Tutorials rund um das Thema Lokalisierung zu zeigen:
- Ein Leitfaden für die React-Lokalisierung mit i18next
- Einführung in JavaScript I18n mit i18next und Moment.js
- React Redux Tutorial: Internationalisierung mit react-i18n-redux
- Erstelle deine eigene i18n-Lösung mit React und Redux
- Lokalisierung von JavaScript- und React-Apps mit LinguiJS
- Lokalisierte serverseitige Darstellung mit React
- Meteor-Anwendungen mit React lokalisieren
- Ein umfassender Leitfaden zur Lokalisierung von React Native
- Alles, was du über i18n mit Gatsby wissen musst (React-basiert)
- Full-Stack JavaScript I18n Schritt für Schritt (mit dem React-basierten Next.js)
Wie lokalisiere ich eine Webseite mit jQuery und i18next?
Auch wenn jQuery heute nicht mehr so angesagt ist wie vor ein paar Jahren, gehört es immer noch zu den beliebtesten JavaScript-Bibliotheken. Du wirst feststellen, dass das Lokalisieren von jQuery-Apps mit der i18next Bibliothek ziemlich einfach ist. Ein offizielles i18next jQuery-Plugin ist ganz einfach einzurichten, also lass uns damit unsere bewährte Demo-App lokalisieren.
🗒 Hinweis » Wir haben i18next ausführlicher weiter oben in diesem Artikel behandelt, daher konzentrieren wir uns hier auf die jQuery-Integration.
Wenn du mitgelesen hast, wird dir die folgende Starter-App bekannt vorkommen. Sie dient als gute Grundlage für unsere Lokalisierungsarbeit.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<div class="container">
<nav class="navbar">
<div class="container">
<ul class="navbar-list navbar-start">
<li class="navbar-item">
<a href="#" data-i18n="home" class="navbar-link">
Startseite
</a>
</li>
<li class="navbar-item">
<a href="#" data-i18n="about" class="navbar-link">
Über
</a>
</li>
</ul>
<div class="navbar-end">
<img src="img/translation-icon@2x.png" class="translation-icon" />
<select data-i18n-switcher class="locale-switcher">
<option value="en">Englisch</option>
<option value="ar">Arabisch (العربية)</option>
</select>
</div>
</div>
</nav>
<h1 data-i18n="app-title">jQuery i18n</h1>
<p data-i18n="lead" data-i18n-options='{"username": "Jackie"}'>
Willkommen in meiner kleinen Ecke im Netz, {{username}}!
</p>
<p data-i18n="new-messages" data-i18n-options='{"count": 3}'>
Du hast {{count}} neue Nachrichten
</p>
</div>
</body>
</html>
🗒 Hinweis » Standardmäßig verwendet das i18next jQuery-Plugin data-i18n (nicht wie zuvor data-i18n-key) als Übersetzungsschlüssel. Das kannst du in den Plugin-Optionen ändern.

Zeit zum Lokalisieren? Los geht's.
Installation
Der einfachste Weg, i18next und das jQuery-Plugin zu installieren, ist, ihre minifizierten Distributionsdateien herunterzuladen und sie in dein HTML einzubinden. Du kannst die Dateien an den folgenden Orten abrufen.
🔗 Ressource » Schau dir die offizielle Dokumentation des i18next jQuery Plugins auf GitHub an.
Nachdem du die oben genannten Dateien heruntergeladen hast, kannst du sie in ein js/lib Verzeichnis in deinem Projekt ablegen und in deine Haupt-HTML-Seite einbinden.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<div class="container">
<!-- ... -->
</div>
<script src="./js/lib/jquery-3.6.0.min.js"></script>
<script src="./js/lib/i18next.min.js"></script>
<script src="./js/lib/jquery-i18next.min.js"></script>
<!-- Unser benutzerdefiniertes JavaScript kommt gleich... -->
<script src="./js/scripts.js"></script>
</body>
</html>
Grundübersetzungen
Mit unseren installierten Bibliotheken können wir jetzt etwas Setup-Code schreiben, um die grundlegende Lokalisierungsarbeit zum Laufen zu bringen.
// i18next initialisieren
i18next.init({
lng: "en", // Ausgangssprache
debug: true, // Bietet hilfreiche Konsolenmeldungen
resources: { // Übersetzungen
en: {
translation: {
"app-title": "jQuery + i18next",
},
},
ar: {
translation: {
"app-title": "جي كويري + آي إيتين نيكست",
},
},
},
});
// i18next jQuery Plugin initialisieren
jqueryI18next.init(i18next, $);
// Seitenelemente übersetzen
$("body").localize();
Wir haben i18next.init(...) bereits früher in diesem Artikel behandelt. Beachte, dass wir hier auch einen jQueryI18next.init(...) Aufruf haben. Im einfachsten Fall nimmt die jQuery i18next Plugin init Funktion die aktive i18next Instanz sowie einen Verweis auf das jQuery-Objekt $.
Wenn das Plugin initialisiert wird, fügt es eine localize()-Funktion zu jQuery hinzu. Wenn du $(selector).localize() aufrufst, lokalisiert das Plugin alle Elemente unter der ausgewählten Hierarchie. Für jedes Element wird, wenn ein data-i18n Attribut gefunden wird, die entsprechende Übersetzung für die aktive Sprache eingefügt.
Ein Beispiel:
// In unserem JavaScript
i18next.init({
lng: "en",
Ressourcen: {
en: {
translation: {
"app-title": "jQuery + i18next",
},
},
ar: {
translation: {
"app-title": "جي كويري + آي إيتين نيكست",
},
},
},
});
jqueryI18next.init(i18next, $);
$("#main-title").localize();
// In unserem HTML
<h1 id="main-title" data-i18n="app-title"></h1>
// Wird gerendert als
<h1 id="main-title" data-i18n="app-title">jQuery + i18next</h1>
Schön und einfach 😊

Und wenn wir unsere Ausgangssprache auf Arabisch ändern, indem wir lng auf "ar" ändern, bekommen wir stattdessen einen arabischen Titel.

Asynchrones Laden von Übersetzungsdateien
Wie wäre es, wenn wir unsere Übersetzungsdateien in separate Dateien aufteilen, eine pro Sprachvariante? Ich höre, wie du fragst. Keine Sorge, das offizielle i18next HTTP-Backend-Plugin deckt das ab.
Um das Plugin zu installieren, schnapp dir das minimierte Verteilungsskript von GitHub und leg es in dein js/lib Verzeichnis. Klar, wir wollen es auch in unser HTML einfügen.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<div class="container">
<!-- ... -->
</div>
<script src="./js/lib/jquery-3.6.0.min.js"></script>
<script src="./js/lib/i18next.min.js"></script>
<script src="./js/lib/i18nextHttpBackend.min.js"></script>
<script src="./js/lib/jquery-i18next.min.js"></script>
<script src="./js/scripts.js"></script>
</body>
</html>
Jetzt können wir unsere App skalierbar machen, indem wir die Übersetzungen in separate JSON-Dateien auslagern.
{
"app-title": "Mit jQuery + i18next"
"home": "Home",
"about": "Über"
}
{
"app-title": "مع جي كويري و آي إيتين نيكست"
"home": "الرئيسية",
"about": "نبذة عنا",
}
Wir müssen unseren Setup-Code überarbeiten, um das HTTP-Plugin zu verwenden(), bei der Initialisierung von i18next. Warte auch, bis die Übersetzungsdatei deiner Ausgangssprache heruntergeladen ist, bevor du versuchst, die Seitenelemente zu übersetzen.
// Warten auf Übersetzungen, die über das Netzwerk übertragen werden
// bevor das jQuery-Plugin initialisiert wird
async function initI18n() {
// Verwende das Http-Backend-Plugin, um Übersetzungen herunterzuladen
await i18next.use(i18nextHttpBackend).init({
lng: "en",
// Entferne die `resources`-Option, da unsere Übersetzungen
// befinden sich jetzt in JSON-Dateien
});
jqueryI18next.init(i18next, $);
}
// Refaktorisieren zu Funktion
function translatePage() {
$("body").localize();
}
// Init
(async function () {
// Warten, bis i18next initialisiert ist
// Seitenelemente übersetzen
await initI18n();
translatePage();
})();
Wenn wir unsere App neu laden, bemerken wir keinen Unterschied in der Ausgabe. Ein näherer Blick auf den Netzwerk-Tab der Entwicklertools zeigt eine wartungsfreundlichere „Lade es herunter, wenn du es brauchst“-Lösung für Übersetzungsdateien.

Sprachumschalter
Vielleicht ist dir aufgefallen, dass wir etwas HTML haben, das wie eine Sprachumschalter-UI in unserer Demo aussieht.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<div class="container">
<nav class="navbar">
<div class="container">
<!-- ... -->
<div class="navbar-end">
<img src="img/translation-icon@2x.png" class="translation-icon" />
<select data-i18n-switcher class="locale-switcher">
<option value="en">Englisch</option>
<option value="ar">Arabisch (العربية)</option>
</select>
</div>
</div>
</nav>
<!-- ... -->
</div>
<!-- ... -->
</body>
</html>
Lass uns das <select>-Element oben so verknüpfen, dass unsere App ihre Übersetzungen auf die vom Benutzer ausgewählte Sprache umschaltet.
// ...
function bindLocaleSwitcher() {
const $switcher = $("[data-i18n-switcher]");
// Anfangswert
$switcher.val(i18next.language);
$switcher.on("change", async function () {
// Das Ändern der aktiven Sprache führt dazu, dass ihre
// Übersetzungen aus dem Netzwerk laden, damit
// Wir warten auf das Laden, bevor wir aktualisieren
// Seitenelemente
await i18next.changeLanguage($switcher.val());
translatePage();
});
}
(async function () {
await initI18n();
translatePage();
bindLocaleSwitcher();
})();
Und schon haben wir einen funktionierenden Sprachumschalter.

Interpolation
Der Umgang mit dynamischen Werten in unseren Übersetzungen ist mit i18next sofort verfügbar. Wir müssen nur eine data-i18n-options JSON-Map im Element bereitstellen, für das wir Interpolationen haben.
<!-- ... -->
<p data-i18n="lead" data-i18n-options='{"username": "Jackie"}'>
Willkommen in meinem kleinen Bereich im Netz, {{username}}!
</p>
<!-- ... -->
Das i18next jQuery-Plugin sucht standardmäßig nicht nach data-i18n-options; wir müssen seine useOptionsAttr Konfigurationsoption verwenden, um die automatische Interpolation zu aktivieren.
async function initI18n() {
await i18next.use(i18nextHttpBackend).init({ lng: "en" });
jqueryI18next.init(i18next, $, { useOptionsAttr: true });
}
// ...
Lass uns sicherstellen, dass wir die {{variable}} Platzhalter haben, die i18next in unseren Übersetzungsnachrichten erwartet.
{
"app-title": "Mit jQuery + i18next"
"home": "Home",
"about": "Über"
"lead": "Willkommen in meinem kleinen Bereich im Netz, {{username}}!"
}
{
"app-title": "مع جي كويري و آي إيتين نيكست"
"home": "الرئيسية",
"about": "نبذة عنا",
"lead": "أهلاً بك في مكاني الصغير على النت يا {{username}}."
}
Los geht's. Interpolationen wurden interpoliert.


Pluralformen
Wir verwenden dasselbe data-i18n-options Attribut, um eine spezielle count Zählervariable bereitzustellen, wenn wir Pluralformen haben.
🗒 Hinweis » Schau dir den vorherigen i18next ➞ Pluralformen Abschnitt an, um mehr darüber zu erfahren, wie die Bibliothek mit Pluralformen arbeitet.
<!-- ... -->
<p data-i18n="new-messages" data-i18n-options='{"count": 3}'>
Du hast {{count}} neue Nachrichten
</p>
<!-- ... -->
Wir verwenden eine key_form-Konvention, wenn wir unsere Pluralnachrichten angeben. Englisch hat zwei Pluralformen, one und other.
{
// ...
"new-messages_one": Du hast {{count}} neue Nachricht
"new-messages_other": "Du hast {{count}} neue Nachrichten"
}
Arabisch hat sechs Pluralformen, und sie werden automatisch von i18next behandelt.
{
// ...
"new-messages_zero": "لا توجد لديك رسائل جديدة",
"new-messages_one": "لديك رسالة جديدة",
"new-messages_two": "لديك رسالتان جداد",
"new-messages_few": "لديك {{count}} رسائل جديدة",
"new-messages_many": "لديك {{count}} رسالة جديدة",
لديك {{count}} رسالة جديدة
}
So hat unsere App ohne zusätzlichen Code eine komplexe Pluralunterstützung.


🔗 Ressource » Hol dir den voll funktionsfähigen Code für die obige App aus unserem GitHub-Repo.
🔗 Ressource » Wenn du nach einer Alternative zu i18next suchst, schau dir The Advanced Guide to jQuery i18n an, der die jQuery.i18n Bibliothek verwendet.
Wie lokalisiere ich eine Webseite mit dem ICU-Format unter Verwendung von Globalize?
Wenn du die nahezu vollständige Lokalisierungsabdeckung der International Components for Unicode (ICU) und des Unicode Common Locale Data Repository (CLDR) in deiner JavaScript-App haben möchtest, erledigt die Globalize Bibliothek das auf jeden Fall. Lass uns gemeinsam anschauen, wie du Globalize installierst und damit unsere bescheidene Demo-App lokalisierst.
🔗 Ressource » Der fehlende Leitfaden zum ICU-Nachrichtenformat behandelt ausführlicher, was ICU und CLDR sind.
🗒 Hinweis » Im Gegensatz zu vielen anderen Bibliotheken, die wir in diesem Artikel behandeln, unterstützt Globalize tatsächlich Internet Explorer 9+.
Welche Demo? sagst du. Unser zuverlässiger One-Pager, natürlich.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<div class="container">
<nav class="navbar">
<div class="container">
<ul class="navbar-list navbar-start">
<li class="navbar-item">
<a href="#" data-i18n-key="home" class="navbar-link">
Startseite
</a>
</li>
<li class="navbar-item">
<a href="#" data-i18n-key="about" class="navbar-link">
Über
</a>
</li>
</ul>
<div class="navbar-end">
<img src="img/translation-icon@2x.png" class="translation-icon" />
<select data-i18n-switcher class="locale-switcher">
<option value="en">Englisch</option>
<option value="ar">Arabisch (العربية)</option>
</select>
</div>
</div>
</nav>
<h1 data-i18n-key="app-title">Mit Globalize</h1>
<p data-i18n-key="lead" data-i18n-opt='{"username": "Stella"}'>
Willkommen auf meiner kleinen Ecke im Internet, {username}!
</p>
<p data-i18n-key="new-messages" data-i18n-opt='{"count": 100}'>
Du hast # neue Nachrichten
</p>
</div>
</body>
</html>

Fang mit der Lokalisierung an.
Installation
Globalize ist sehr modular, daher kann die Installation mit reinem JavaScript etwas umständlich sein. Dennoch ist es ein relativ einfaches Rezept.
- Lade die neueste Globalize-Version herunter
- Lade die neueste CLDR-Traverser (cldr.js)-Version herunter
- Lade die neueste CLDR JSON-Datenversion herunter – stell sicher, dass du die
-fullVariante aus der Veröffentlichungsübersicht herunterlädst, um hier mitmachen zu können.
Das sollte uns drei ZIP-Dateien geben. Lass sie uns entpacken, ihre entpackten obersten Verzeichnisse umbenennen und in unser Projektverzeichnis verschieben. Ich habe meins unter dem Verzeichnis /lib in meinem Projekt abgelegt, sodass mein Projekt jetzt so aussieht:
. ├── css/ ├── img/ ├── lib/ │ ├── cldr/ << umbenannt von cldr-x.x.x │ ├── cldr-json/ << umbenannt von cldr-x.x.x-json-full │ └── globalize/ << umbenannt von globalize.x.x └── index.html
🔗 Ressource » Die offizielle Dokumentation beschreibt verschiedene Möglichkeiten, Globalize zu installieren.
Verwendung des Anforderungstools zur Bestimmung der benötigten Skripte
Wir benötigen immer einige Teile von Globalize und cldr.js; andere hängen von den Lokalisierungsfunktionen unserer App ab. Ein praktisches Tool, So What’cha Want, kann dir sagen, welche Dateien du je nach deinen ausgewählten Funktionen in dein Projekt holen solltest. Wir können beginnen, indem wir alle Funktionen abwählen, außer message.

Beachte die beiden Dateilisten am unteren Ende der Seite. Die Liste auf der linken Seite zeigt an, welche Dateien von Globalize und cldr.js importiert werden sollen; wir können <script>-Tags dafür verwenden.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<div class="container">
<!-- ... -->
</div>
<!-- Globalize-Anforderungen -->
<script src="./lib/cldr/dist/cldr.js"></script>
<script src="./lib/cldr/dist/cldr/event.js"></script>
<script src="./lib/cldr/dist/cldr/supplemental.js"></script>
<script src="./lib/globalize/dist/globalize.js"></script>
<script src="./lib/globalize/dist/globalize/message.js"></script>
<!-- Unser App-Einstiegspunkt -->
<script src="./index.js"></script>
</body>
</html>
Die Liste unten rechts von So What'cha Want enthält CLDR JSON-Daten, die wir benötigen. Hol dir dieses JSON in deinen Code und gib es an Globalize über die load() Funktion weiter.
// Wir fügen nach und nach mehr zu dieser Liste hinzu
const supplementals = ["likelySubtags"];
async function loadIntoGlobalize(featureUrls) {
await Promise.all(
featureUrls.map((url) => fetchJson(url))
).then((downloaded) =>
downloaded.forEach((feature) => Globalize.load(feature))
);
}
function supplementalUrlsFor(options) {
return options.map(
(feature) =>
`/lib/cldr-json/cldr-core/supplemental/${feature}.json`
);
}
async function fetchJson(url) {
const response = await fetch(url);
return await response.json();
}
(async function () {
// Lade ergänzende Anforderungen
await loadIntoGlobalize(
supplementalUrlsFor(supplementals)
);
})();
Das war's mit der Einrichtung. OK, nicht die einfachste Bibliothek zu installieren, aber für ein Projekt, das eine zuverlässige Lokalisierung benötigt, ist es die Mühe wert.
Grundlegende Übersetzungen
Die Verwendung von Globalize zur Übersetzung von Seitenelementen ist ein einfacher dreistufiger Prozess.
// ...
(async function () {
await loadIntoGlobalize(
supplementalUrlsFor(supplementals)
);
// 1. Lade Übersetzungsnachrichten
Globalize.loadMessages({
en: {
"app-title": "Hallo Globalize!",
},
ar: {
"app-title": "أهلاً جلوبالايز",
},
});
// 2. Setze die Standardsprache
Globalize.locale("en");
// 3. Verwende formatMessage(), um die Übersetzung anhand des Schlüssels zu erhalten
document.querySelector(
"[data-i18n-key='app-title']"
).textContent = Globalize.formatMessage("app-title");
})();
🔗 Ressource » Die offizielle Globalize-Dokumentation hat einen praktischen API-Abschnitt, der verfügbare Funktionen auflistet.
Disco. Unser Titel wird mit der Übersetzung unserer Standardsprache angezeigt.

Wenn wir den obigen Aufruf ändern, so dass er Globalize.locale("ar") lautet, erhalten wir den Titel unserer App auf Arabisch.

Fehlende Nachrichten behandeln
Verallgemeinere den Code, der Seitenelemente übersetzt, indem du eine translatePageElements() Funktion schreibst. Im Gegensatz zu anderen i18n-Bibliotheken löst Globalize einen Fehler aus und stoppt, wenn bei einem bestimmten Schlüssel für formatMessage() eine Nachricht fehlt. Nichts, was ein wenig try/catch nicht abmildern könnte.
// ...
function translatePageElements() {
const elements = document.querySelectorAll(
"[data-i18n-key]"
);
elements.forEach((element) => {
const key = element.getAttribute("data-i18n-key");
try {
element.innerHTML = Globalize.formatMessage(key);
} catch (error) {
if (error.code === "E_MISSING_MESSAGE") {
// Zeig Konsolenwarnungen bei fehlenden Nachrichten an
// anstatt zum Stillstand zu kommen.
console.warn(error.message);
// Zeige den Schlüsselwert auf der Seite für eine fehlende Nachricht an
element.innerHTML = key;
} else {
console.error(error);
}
}
});
}
(async function () {
// ...
Globalize.loadMessages(/* ... */);
Globalize.locale("en");
translatePageElements();
})();
Weniger "Absturz bei fehlender Nachricht", mehr "Schlüsselwert anzeigen und in der Konsole warnen".

Asynchrones Laden von Übersetzungsdateien
Wie wir es mit anderen Lösungen in diesem Artikel gemacht haben, lass uns unsere Übersetzungsnachrichten in JSON-Dateien pro Locale aufteilen, um Skalierbarkeit und Wartbarkeit zu gewährleisten.
{
// Globalize erwartet, dass der Sprachcode der oberste Schlüssel ist
"en": {
"app-title": "Mit Globalize"
"home": "Home",
"about": "Über"
}
}
{
"ar": {
"app-title": "مع جلوبالايز",
"home": "الرئيسية",
"about": "نبذة عنا"
}
}
Eine wiederverwendbare setLocale()-Funktion kann unsere Übersetzungsdatei laden, Globalize konfigurieren und unsere Seitenelemente neu rendern.
const defaultLocale = "en";
// ...
async function setLocale(locale) {
const messages = await fetchJson(`/lang/${locale}.json`);
Globalize.loadMessages(messages);
Globalize.locale(locale);
translatePageElements();
}
// ...
(async function () {
await loadIntoGlobalize(
supplementalUrlsFor(supplementals)
);
setLocale(defaultLocale);
})();
Asynchrones Laden der Übersetzungsdatei: erledigt.
Sprachumschalter
Wir können die Funktion setLocale(), die wir gerade geschrieben haben, verwenden, um unsere Sprachumschaltung zum Laufen zu bringen. Vielleicht erinnerst du dich, dass unsere Demo-App bereits etwas HTML für den Umschalter hat.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<div class="container">
<nav class="navbar">
<div class="container">
<!-- ... -->
<div class="navbar-end">
<img src="img/translation-icon@2x.png" class="translation-icon" />
<select data-i18n-switcher class="locale-switcher">
<option value="en">Englisch</option>
<option value="ar">Arabisch (العربية)</option>
</select>
</div>
</div>
</nav>
<!-- ... -->
</div>
<!-- ... -->
<script src="./index.js"></script>
</body>
</html>
Ein bisschen JavaScript bringt den Umschalter zum Umschalten.
const defaultLocale = "en";
// ...
function bindLocaleSwitcher() {
const switcher = document.querySelector(
"[data-i18n-switcher]"
);
// Globalize.locale() gibt das aktive Gebietsschema zurück
switcher.value = Globalize.locale().locale;
switcher.onchange = (e) => {
setLocale(e.target.value);
};
}
(async function () {
await loadIntoGlobalize(
supplementalUrlsFor(supplementals)
);
await setLocale(defaultLocale);
bindLocaleSwitcher(defaultLocale);
})();
Und damit kannst du die Sprache auswählen, die du bevorzugst.

Zeige die Sprachbezeichnungen in der aktiven Sprache an
Eines der mächtigsten Features, wenn du eine ICU-Bibliothek wie Globalize nutzt, ist der Zugriff auf eine immens große Vielfalt an CLDR-Lokalisierungsdaten. Zum Beispiel kannst du die Sprachen in deinem Sprachumschalter im aktiven Gebietsschema anzeigen – Englisch wäre zum Beispiel „الإنجليزية“ auf Arabisch. Wir müssten die Haupt-CLDR-Daten importieren und dann unseren select > option Text aktualisieren.
const defaultLocale = "ar";
const mains = {
localenames: ["languages"],
};
const supplementals = "likelySubtags"];
async function setLocale(locale) {
const messages = await fetchJson(`/lang/${locale}.json`);
Globalize.loadMessages(messages);
await loadIntoGlobalize(mainUrlsFor(mains, locale));
Globalize.locale(locale);
translatePageElements();
setLocaleSwitcherDisplayNames();
}
// Given options = {
// localenames: ["languages"],
// Daten: ["ca-generic", "ca-gregorian"],
// }
// und, locale = "en", gibt ein Array zurück wie folgt
// [
// "/lib/cldr-json/cldr-localenames-full/main/en/languages.json",
// "/lib/cldr-json/cldr-dates-full/main/en/ca-generic.json",
// "/lib/cldr-json/cldr-dates-full/main/en/ca-gregorian.json"
// ]
function mainUrlsFor(options, locale) {
const result = [];
Object.keys(options).forEach((key) => {
options[key].forEach((collection) => {
result.push(
`/lib/cldr-json/cldr-${key}-full/main/${locale}/${collection}.json`
);
});
});
return result;
}
function setLocaleSwitcherDisplayNames() {
const options = document.querySelectorAll(
"[data-i18n-switcher] option"
);
options.forEach((option) => {
const localeCode = option.value;
// Hol dir die CLDR-Hauptdaten über den Pfad
option.textContent = Globalize.cldr.main(
`localeDisplayNames/languages/${localeCode}`
);
});
}
// ...
Du kannst unseren Haupt-JSON-Ladecode verwenden, wann immer du die CLDR-JSON-Hauptdaten abrufen willst. Andernfalls sorgt ein wenig DOM-Manipulation dafür, dass wir beim Auswählen eines neuen Gebietsschemas lokalisierte Locale-Namen erhalten (so meta!).

🔗 Ressource » Die offiziellen cldr.js-Dokumente erklären ausführlicher, wie du CLDR-JSON-Daten abrufen kannst.
Interpolation
Die Verarbeitung dynamischer Werte in unserer Nachricht erfolgt über das ICU-Nachrichtenformat mit einer {variable} Syntax.
{
"en": {
// ...
"lead": "Willkommen in meinem kleinen Eckchen im Internet, {username}!"
}
}
{
"ar": {
// ...
"lead": "أهلاً بك في مكاني الصغير على النت يا {username}."
}
}
Wir können Schlüssel/Wert-Ersetzungspaare in unserem HTML bereitstellen.
<!-- ... -->
<p data-i18n-key="lead" data-i18n-opt='{"username": "Stella"}'>
Willkommen in meiner kleinen Ecke im Netz, {username}!
</p>
<!-- ... -->
Und jetzt müssen wir nur noch diese Schlüssel-Wert-Paare lesen und sie an Globalize.formatMessage() übergeben.
// ...
function translatePageElements() {
const elements = document.querySelectorAll(
"[data-i18n-key]"
);
elements.forEach((element) => {
const key = element.getAttribute("data-i18n-key");
const interpolations =
element.getAttribute("data-i18n-opt");
const parsedInterpolations = interpolations
? JSON.parse(interpolations)
: {};
try {
element.innerHTML = Globalize.formatMessage(
key,
parsedInterpolations
);
} catch (error) {
if (error.code === "E_MISSING_MESSAGE") {
console.warn(error.message);
} else {
console.error(error);
}
}
});
}
// ...
Kein Problem.


Pluralformen
Die Handhabung von Pluralformen im ICU-Format ist unübertroffen und deckt komplexe Pluralformen wie die in Russisch oder Arabisch ab. Wir müssen die Pluralfunktion einrichten, bevor wir sie verwenden können.
Pluralanforderungen hinzufügen
Lass uns zu So What’cha Want gehen, um herauszufinden, was wir einbeziehen müssen, wenn wir plural aktivieren.

Gar nicht schlecht: Zuerst müssen wir ein <script>-Tag für die Funktion hinzufügen.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<div class="container">
<!-- ... -->
</div>
<script src="./lib/cldr/dist/cldr.js"></script>
<script src="./lib/cldr/dist/cldr/event.js"></script>
<script src="./lib/cldr/dist/cldr/supplemental.js"></script>
<script src="./lib/globalize/dist/globalize.js"></script>
<script src="./lib/globalize/dist/globalize/message.js"></script>
<script src="./lib/globalize/dist/globalize/plural.js"></script>
<script src="./index.js"></script>
</body>
</html>
Wir benötigen außerdem die ergänzende JSON für plurals und wahrscheinlich auch die für ordinals, wenn wir Formatierungen wie „3.“ und „4.“ in unseren Nachrichten abdecken wollen. Wir müssen nur die Anforderungen zu unserem supplementals-Konfigurationsarray hinzufügen. Unsere App ist bereits so eingerichtet, dass sie das entsprechende JSON für uns beim Start lädt.
const defaultLocale = "ar"; const supplementals = [ "likelySubtags", "plurals", "ordinals", ]; // ...
Jetzt können wir unsere Pluralnachrichten hinzufügen. Die ICU-Plural-Syntax ist weitgehend intuitiv: Eine count-Variable bestimmt die gewählte Pluralform, und ein spezielles #-Symbol wird beim Anzeigen durch den count-Wert ersetzt.
{
"en": {
// ...
"neue-nachrichten": [
// Wir können `count` nennen, wie wir wollen, solange wir möchten.
// den Schlüssel in unserem Aufruf von formatMessage() abstimmen
"Du hast {count, plural,",
one {# neue Nachricht}
other {# neue Nachrichten}
"}"
]
}
}
🗒 Hinweis » Globalize ermöglicht es uns, mehrzeilige Nachrichten durch die Verwendung von Arrays aufzuteilen.
Die sechs Pluralformen im Arabischen werden durch das ICU-Format behandelt.
{
"ar": {
// ...
"neue-nachrichten": [
"{count, plural, ",
" zero {لا توجد لديك رسائل جديدة}",
one {لديك رسالة جديدة}
two {لديك رسالتان جداد}
few {لديك # رسائل جديدة}
many {لديك # رسالة جديدة}
" other {لديك # رسالة جديدة}",
"}"
]
}
}
🤿 Gehe tiefer » Wir behandeln ICU-Mehrzahlformen ausführlicher in "Der fehlende Leitfaden zum ICU-Nachrichtenformat".
Natürlich müssen wir sicherstellen, dass count an Globalize.formatMessage() übergeben wird.
<!-- ... -->
<p data-i18n-key="new-messages" data-i18n-opt='{"count": 110}'>
Du hast # neue Nachrichten
</p>
<!-- ... -->
Und damit sind die Pluralformen im Grunde erledigt.


🗒 Hinweis » Die ICU-Implementierung von Globalize bietet umfassende Datums- und Zahlenformatierung. Schau dir die offizielle Dokumentation an, um mehr zu erfahren.
🔗 Ressource » Wir behandeln weitere Globalize-Installationsoptionen und Anwendungsfälle in JS I18n mit Globalize.js.
Wir beenden unseren JavaScript-Lokalisierungsleitfaden
Und das war's für dieses Mal. Wir hoffen, du hast diesen Ausflug in einige der beliebtesten JavaScript-Lokalisierungslösungen genossen.
🔗 Ressource » Wenn du mit Ruby on Rails arbeitest, könnte dir JavaScript in Rails-Apps lokalisieren gefallen.
Und wenn du deinen Lokalisierungsprozess auf die nächste Stufe heben willst, schau dir Phrase an. Phrase unterstützt das ICU-Format, alle anderen hier behandelten Übersetzungsformate und viele mehr. Mit seiner CLI und der Synchronisierung mit Bitbucket, GitHub und GitLab läuft deine i18n wie von selbst. Die voll ausgestattete Phrase-Webkonsole mit maschinellem Lernen und smarten Vorschlägen macht richtig Spaß beim Übersetzen. Sobald die Übersetzungen bereit sind, können sie automatisch mit deinem Projekt synchronisiert werden. Einmal eingestellt, kannst du es vergessen und dich ganz auf den Code konzentrieren, den du liebst.
Schau dir alle Phrase-Funktionen für Entwickler an und überzeuge dich selbst, wie es deine Software-Lokalisierungs-Workflows vereinfachen kann.



