JavaScript Navigator languages Property

Beginner
5 min read
Updated: Nov 2026
5 examples
Property

Definition

navigator.languages is a read-only Navigator property that returns an array of strings — the user’s preferred languages as BCP 47 tags, ordered with the most preferred language first (MDN).

Read the notes below before you rely on this property. Prefer feature detection when support is limited.

Syntax

Use navigator.languages. Start with this line.

JavaScript
navigator.languages
CallWhat it does
navigator.languagesPrimary signature.

Built into the browser. Read navigator.languages on Navigator — no import required.

Library declarations
JavaScript
navigator.languages

Parameters

ParameterDescription
languages[0]Optional. Top preference (≈ language)
Intl.* constructorsOptional. Locale negotiation with fallback
languagechangeOptional. Re-read prefs when they change

Return Value

Return ValueDescription
*The current value of navigator.languages.

JavaScript Examples

Example 1 — Read the Preference List

Log navigator.language and navigator.languages together (MDN listing style).

JavaScript
console.log(navigator.language);
console.log(navigator.languages);
console.log("count: " + navigator.languages.length);
Try It Yourself

How It Works

  1. Read one tag. navigator.language is the top preference as a string.
  2. Read the array. navigator.languages lists preferences in order.
  3. Check length. Useful when you only care whether more than one locale exists.
  4. Expect variation. Tags and list length differ by browser and privacy mode.

Example 2 — First Item Equals language

Confirm that languages[0] matches navigator.language.

JavaScript
const first = navigator.languages[0];

console.log("languages[0]: " + first);
console.log("language: " + navigator.language);
console.log("same?: " + (first === navigator.language));
Try It Yourself

How It Works

  1. Take index 0. That is the most preferred language.
  2. Compare to language. MDN states they match.
  3. Choose the API. Need one tag? Use language. Need the list? Use languages.
  4. Stay read-only. You cannot assign a new preference from your page.

Example 3 — Intl Formatting with Fallback (MDN)

Pass the preference array to Intl.DateTimeFormat for locale negotiation.

JavaScript
const date = new Date("2012-05-24");
const formattedDate = new Intl.DateTimeFormat(
  navigator.languages
).format(date);

console.log("prefs: " + JSON.stringify(navigator.languages));
console.log("formatted: " + formattedDate);
Try It Yourself

How It Works

  1. Build a date. Fixed ISO string keeps the demo predictable.
  2. Pass the array. Intl walks preferences until it finds a supported locale.
  3. Format once. format(date) returns a locale-aware string.
  4. Reuse the idea. Same pattern works for Intl.NumberFormat and friends.

Example 4 — Match Against Supported Locales

Pick the first user preference that your app actually ships.

JavaScript
function matchLocale(supported, fallback) {
  const prefs = navigator.languages.map((t) => t.toLowerCase());
  for (const tag of prefs) {
    if (supported.includes(tag)) return tag;
    const primary = tag.split("-")[0];
    if (supported.includes(primary)) return primary;
  }
  return fallback;
}

console.log("prefs: " + JSON.stringify(navigator.languages));
console.log("picked: " + matchLocale(["en", "fr", "es", "ja"], "en"));
Try It Yourself

How It Works

  1. Normalize case. Compare lowercase tags for simple matching.
  2. Try the full tag. Exact match like en-us if you ship region codes.
  3. Fall back to primary. en-US → en when you only ship language codes.
  4. Use a default. Return fallback when nothing matches.

Example 5 — Listen for languagechange

Re-read preferences when the user changes browser language settings.

JavaScript
function report() {
  return {
    languages: navigator.languages,
    language: navigator.language
  };
}

console.log(JSON.stringify(report(), null, 2));

window.addEventListener("languagechange", () => {
  console.log("updated:");
  console.log(JSON.stringify(report(), null, 2));
});
Try It Yourself

How It Works

  1. Snapshot once. Log the current preference list on load.
  2. Subscribe on window. MDN fires languagechange on the global scope.
  3. Re-read the property. The event itself has no language payload — read navigator.languages again.
  4. Refresh UI. Re-run Intl formatters or reload translated strings after a change.

Browser Support

navigator.languages is Baseline Widely available (MDN). Evergreen browsers have shipped it since about October 2017.

✓ Baseline · Widely available

Navigator.languages

Supported in modern Chrome, Firefox, Safari, Edge, and Opera. Use a fallback locale when the list is short or empty in privacy modes.

98% Modern browser support
Google Chrome Supported · Desktop & Mobile
Full support
Mozilla Firefox Supported · Desktop & Mobile
Full support
Apple Safari Supported · may list one language
Full support
Microsoft Edge Supported · Chromium
Full support
Opera Supported · Modern versions
Full support
Internet Explorer No navigator.languages
Unavailable
navigator.languages Excellent

Bottom line: Safe for modern web apps. Always keep an app-level default locale — privacy modes may expose only one tag.

Frequently Asked Questions

A read-only array of BCP 47 language tags for the user’s preferred languages, ordered with the most preferred language first (MDN).
No. MDN marks it Baseline Widely available (since about October 2017). It is not Deprecated, Experimental, or Non-standard.
navigator.language is the first element of navigator.languages. Use language for one tag; use languages for the full preference list or Intl fallback.
Yes. MDN shows new Intl.DateTimeFormat(navigator.languages).format(date) so Intl can pick the first supported locale from the preference list.
When preferred languages change, a languagechange event fires on the Window. Listen with window.addEventListener("languagechange", …) and re-read navigator.languages.
Not always. For privacy (reducing fingerprinting), some browsers may expose a shorter list — Safari often lists one language, and Chrome’s incognito mode may also limit the list.

Next: locks

Learn how navigator.locks coordinates work across tabs with the Web Locks API.

locks tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

10 people found this page helpful