Signatur
Beschreibung
WorkerNavigator.languages ist das Gegenstück zu Navigator.languages im Worker-Kontext (Dedicated Worker, Shared Worker, Service Worker). Die Eigenschaft liefert ein Array von Sprach-Tags nach BCP 47 (z. B. "de-DE", "en"), sortiert nach Präferenz – der erste Eintrag ist die am stärksten bevorzugte Sprache.
Typische Einsatzzwecke sind die Lokalisierung von Daten direkt im Worker: Formatierung von Zahlen und Datumswerten mit Intl, Auswahl passender Übersetzungsdateien in einem Service Worker oder das sprachabhängige Sortieren großer Datenmengen mit Intl.Collator, ohne den Haupt-Thread zu belasten.
Der erste Eintrag entspricht in der Regel navigator.language. Ändert der Benutzer seine Spracheinstellungen, wird im Worker das Event languagechange auf dem globalen Objekt (self) ausgelöst; danach liefert languages ein neues Array.
Rückgabewert
Beispiele
Bevorzugte Sprachen im Worker auslesen
// worker.js
const langs = self.navigator.languages;
console.log(langs);
console.log(`Primär: ${langs[0]}`);
self.postMessage({ languages: [...langs] });
Daten im Worker lokalisiert formatieren
// worker.js – große Datenmenge formatieren, ohne UI zu blockieren
self.addEventListener('message', ({ data }) => {
const locales = self.navigator.languages;
const fmt = new Intl.NumberFormat(locales, { style: 'currency', currency: 'EUR' });
const collator = new Intl.Collator(locales);
const result = data
.toSorted((a, b) => collator.compare(a.name, b.name))
.map(({ name, price }) => `${name}: ${fmt.format(price)}`);
self.postMessage(result);
});
Übersetzungsdatei im Service Worker wählen und auf Änderungen reagieren
// sw.js
const SUPPORTED = ['de', 'en', 'fr'];
const pickLocale = () => {
for (const tag of self.navigator.languages) {
const base = tag.split('-')[0].toLowerCase();
if (SUPPORTED.includes(base)) return base;
}
return 'en'; // Fallback
};
let currentLocale = pickLocale();
self.addEventListener('languagechange', () => {
currentLocale = pickLocale();
console.log('Neue Sprache:', currentLocale);
});
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
if (url.pathname === '/i18n/messages.json') {
event.respondWith(fetch(`/i18n/${currentLocale}.json`));
}
});
// Wichtig · Fallstricke
- Das Array ist eingefroren (
Object.isFrozen(navigator.languages) === true);push()odersort()werfen im Strict Mode einenTypeError. Für Bearbeitungen vorher kopieren:[...navigator.languages]. - Die Werte stimmen nicht zwingend mit dem HTTP-Header
Accept-Languageüberein; manche Browser (z. B. Firefox mitprivacy.resistFingerprinting, Tor Browser) liefern aus Datenschutzgründen nur["en-US"]o. Ä. - Schreibweise der Tags variiert (
"en-us"vs."en-US") – beim Vergleich normalisieren oderIntl.getCanonicalLocales()nutzen. - Die Eigenschaft kann ein leeres Array liefern; immer einen Fallback vorsehen.
Intl-Konstruktoren akzeptieren das Array direkt und fallen selbst auf die Standard-Locale zurück. - Sprachpräferenzen tragen zum Browser-Fingerprinting bei – nur so weit auswerten und übertragen, wie es für die Funktion nötig ist.
- Kompatibilität: in allen aktuellen Browsern verfügbar, in sehr alten Versionen (z. B. Chrome < 61) fehlt die Eigenschaft im Worker; ggf. mit
navigator.languages ?? [navigator.language]absichern.