Start · Sprachen · JavaScript · Referenz · Navigator.languages

Navigator.languages

Eigenschaft

Schreibgeschützte Eigenschaft, die ein eingefrorenes Array von BCP-47-Sprach-Tags mit den bevorzugten Sprachen des Benutzers liefert, sortiert nach Priorität.

seit JavaScript Baseline: alle modernen Browser (Chrome 32+, Firef Kategorie: webapi

Signatur

Navigator.languages

Beschreibung

navigator.languages gibt ein schreibgeschütztes Array von Sprach-Tags nach BCP 47 zurück, etwa ["de-DE", "de", "en-US", "en"]. Die Reihenfolge entspricht den Einstellungen des Benutzers: Das erste Element ist die bevorzugte Sprache und stimmt in der Regel mit navigator.language überein.

Die Eigenschaft eignet sich, um im Client die passende Sprache für die Oberfläche auszuwählen, Übersetzungsdateien nachzuladen oder Intl-Formatierer (Intl.DateTimeFormat, Intl.NumberFormat) mit einer sinnvollen Liste von Locale-Werten zu versorgen. Weil Intl-Konstruktoren direkt ein Array von Locales annehmen, kann man navigator.languages ohne Umwege übergeben.

Ändert der Benutzer seine Spracheinstellungen, löst das window-Objekt das Ereignis languagechange aus. Danach liefert navigator.languages ein neues Array-Objekt. Solange sich nichts geändert hat, bekommt man bei jedem Zugriff dasselbe Objekt zurück. Die Werte entsprechen im Wesentlichen dem HTTP-Header Accept-Language, den der Browser mitschickt, allerdings ohne Gewichtungen (q-Werte).

Die Eigenschaft ist auch in Web Workern über WorkerNavigator.languages verfügbar.

Rückgabewert

Typ
ReadonlyArray<string>
Beschreibung
Ein eingefrorenes Array von BCP-47-Sprach-Tags, sortiert nach Präferenz (höchste zuerst). Das Array kann in manchen Umgebungen leer sein.

Beispiele

Bevorzugte Sprachen auslesen

const langs = navigator.languages;
console.log(langs);
console.log(`Bevorzugt: ${langs[0]}`);
console.log(Object.isFrozen(langs));
["de-DE", "de", "en-US", "en"] Bevorzugt: de-DE true

Passende UI-Sprache aus unterstützten Sprachen wählen

const SUPPORTED = ['de', 'en', 'fr'];
const FALLBACK = 'en';

const pickLanguage = () => {
  const prefs = navigator.languages?.length
    ? navigator.languages
    : [navigator.language ?? FALLBACK];

  for (const tag of prefs) {
    // Exakter Treffer oder Basissprache ("de-AT" -> "de")
    const base = tag.toLowerCase().split('-')[0];
    if (SUPPORTED.includes(base)) return base;
  }
  return FALLBACK;
};

const lang = pickLanguage();
document.documentElement.lang = lang;
console.log(`UI-Sprache: ${lang}`);
UI-Sprache: de

Direkt an Intl-Formatierer übergeben

const price = new Intl.NumberFormat(navigator.languages, {
  style: 'currency',
  currency: 'EUR'
}).format(1234.5);

const date = new Intl.DateTimeFormat(navigator.languages, {
  dateStyle: 'long'
}).format(new Date(2024, 2, 15));

console.log(price, '|', date);
1.234,50 € | 15. März 2024

Auf Sprachwechsel reagieren (languagechange)

const onLanguageChange = () => {
  console.log('Neue Sprachen:', navigator.languages.join(', '));
  // z. B. Übersetzungen neu laden
};

window.addEventListener('languagechange', onLanguageChange);

// Später wieder entfernen:
// window.removeEventListener('languagechange', onLanguageChange);
Neue Sprachen: en-US, en, de

// Wichtig · Fallstricke

  • Schreibgeschützt und eingefroren: Zuweisungen wie navigator.languages = [...] oder navigator.languages.push() haben keine Wirkung bzw. werfen im Strict Mode einen TypeError. Zum Bearbeiten zuerst kopieren: [...navigator.languages].
  • Groß-/Kleinschreibung uneinheitlich: Browser liefern teils "en-US", teils "en-us". Vor Vergleichen normalisieren, z. B. mit Intl.getCanonicalLocales() oder toLowerCase().
  • Keine Basissprache garantiert: Die Liste kann nur "de-AT" enthalten, ohne "de". Deshalb beim Abgleich auch auf die Basissprache zurückfallen.
  • Datenschutz/Fingerprinting: Die Sprachliste trägt zum Browser-Fingerprint bei. Datenschutzfreundliche Browser und Modi (Firefox resistFingerprinting, Tor, Brave) melden eventuell nur ["en-US", "en"] oder eine gekürzte Liste. Chrome kürzt die Liste teilweise auf die bevorzugte Sprache.
  • Serverseitig ist der Header Accept-Language meist die bessere Quelle, weil er schon bei der ersten Anfrage da ist. Die Wahl des Benutzers (z. B. Sprachumschalter) sollte immer Vorrang vor der automatischen Erkennung haben.
  • Kompatibilität: In sehr alten Browsern (IE) fehlt die Eigenschaft. Dort auf navigator.language oder das nicht standardisierte navigator.userLanguage zurückfallen. In Node.js (ab 21) gibt es navigator.language, navigator.languages gibt dort nur die Sprache aus der ICU-Standard-Locale zurück.