JavaScript Navigator languages Property

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Baseline

What You’ll Learn

navigator.languages returns an ordered array of BCP 47 language tags. Learn preference order, how it relates to navigator.language, Intl fallback formatting, languagechange, five examples, and try-it labs.

01

Kind

Read-only property

02

Returns

Array of strings

03

Baseline

Widely available

04

Order

Most preferred first

05

First item

navigator.language

06

Event

languagechange

Introduction

Many users prefer more than one language: English first, then Spanish, then French. A single tag is not enough when your site ships several locales and needs a smart fallback chain.

navigator.languages returns that preference list as an array of BCP 47 strings. The first entry is the most preferred language — and MDN notes it matches navigator.language.

💡
Privacy note

MDN warns that for fingerprinting protection, some browsers may expose a shorter list (Safari often lists one language; Chrome incognito may too). Treat the array as a helpful hint, not a guaranteed full profile.

Understanding the languages Property

Think of it as an ordered “wishlist” of languages the user likes.

  • Array of BCP 47 tags — e.g. ["en-US", "zh-CN", "ja-JP"].
  • Preference order — index 0 is the top choice.
  • Link to languagenavigator.language === navigator.languages[0] (typically).
  • Intl fallback — pass the array to Intl constructors for locale negotiation.
  • languagechange — fires on window when preferences change.
  • Accept-Language — HTTP header usually lists similar locales (with q values).

📝 Syntax

General form of the property:

JavaScript
navigator.languages

Value

  • An array of strings (BCP 47 language tags), most preferred first.

Common patterns

JavaScript
// MDN-style listing:
console.log(navigator.language);   // e.g. "en-US"
console.log(navigator.languages);  // e.g. ["en-US", "zh-CN", "ja-JP"]

// Intl with preference-based fallback:
const date = new Date("2012-05-24");
const formattedDate = new Intl.DateTimeFormat(navigator.languages).format(date);

// React when the user changes preferred languages:
window.addEventListener("languagechange", () => {
  console.log(navigator.languages);
});

⚡ Quick Reference

GoalCode
Read preference listnavigator.languages
Top preferencenavigator.languages[0]
Same as language?navigator.languages[0] === navigator.language
Intl with fallbacknew Intl.DateTimeFormat(navigator.languages)
Listen for changeswindow.addEventListener("languagechange", …)
Status (MDN)Baseline Widely available

🔍 At a Glance

Four facts to remember about navigator.languages.

Returns
string[]

BCP 47 tags

Baseline
widely

Since ~Oct 2017

First item
language

Same preference

Event
languagechange

On window

📋 languages vs language

navigator.languagesnavigator.language
TypeArray of stringsSingle string
MeaningOrdered preference listMost preferred language
Relationshiplanguage is the first element of languages
Best forFallbacks + Intl negotiationSimple default locale
HTTP cousinAccept-Language often mirrors the list

Examples Gallery

Examples follow MDN navigator.languages patterns. Prefer Try It Yourself to inspect your preference list and Intl fallback behavior.

📚 Getting Started

Read the array and compare it with navigator.language.

Example 1 — Read the Preference List

Log the array MDN-style alongside navigator.language.

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

How It Works

Order matters: earlier entries are stronger preferences.

Example 2 — First Item Matches language

Confirm the MDN relationship between the two properties.

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

If you only need one tag, navigator.language is enough. Use the array when you need fallbacks.

📈 Practical Patterns

Intl fallback, matching your shipped locales, and languagechange.

Example 3 — Intl Formatting with Fallback

Pass the whole array to Intl so it can pick the first supported locale (MDN).

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

How It Works

Intl walks the preference list until it finds a locale it understands.

Example 4 — Match Against Supported Locales

Pick the first preference that matches a translation pack you ship.

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(matchLocale(["en", "fr", "es", "ja"], "en"));
Try It Yourself

How It Works

Walk the array in order so you honor “French first, English second” correctly.

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()));

window.addEventListener("languagechange", () => {
  console.log("updated: " + JSON.stringify(report()));
});
// Change browser language settings to see the event (when supported).
Try It Yourself

How It Works

The event fires on window, not on navigator. Re-run your locale picker when it fires.

🚀 Common Use Cases

  • i18n fallback chains — try fr-CA, then fr, then en.
  • Intl formatting — pass the array for preference-aware locale selection.
  • Content negotiation — mirror what Accept-Language roughly describes.
  • Live updates — refresh UI copy on languagechange.
  • Defaults with overrides — seed a language picker from the preference list.

🧠 How navigator.languages Works

1

User sets preferred languages

Browser / OS language settings define the list.

Settings
2

Browser exposes an ordered array

navigator.languages (may be shortened for privacy).

Read
3

Your app walks the list

Match translation packs or pass the array to Intl.

Match
4

Update on languagechange

Re-read the array when preferences change at runtime.

📝 Notes

  • Baseline Widely available (MDN, since about October 2017).
  • Not Deprecated, Experimental, or Non-standard — no status banner required.
  • navigator.language is the first element of the returned array.
  • Privacy modes may shorten the list — do not assume a complete preference profile.
  • Related: locks, language, JavaScript hub.

Universal Browser Support

navigator.languages is Baseline Widely available across modern browsers (MDN: since about October 2017). Use the ordered list for fallbacks and Intl negotiation, and remember privacy modes may shorten it.

Baseline · Widely available

Navigator.languages

Read the preferred-language array, pass it to Intl for fallbacks, and listen for languagechange when settings update.

Universal Widely available
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
languages Excellent

Bottom line: Use navigator.languages for preference-ordered fallbacks. Use navigator.language when a single tag is enough.

Conclusion

navigator.languages is the ordered list of preferred BCP 47 tags. Walk it for i18n fallbacks, pass it to Intl, and listen for languagechange when preferences update — while remembering the list may be shortened for privacy.

Continue with locks, language, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Walk the array in order for locale matching
  • Pass the array to Intl for fallback selection
  • Listen for languagechange in long-lived apps
  • Still offer a manual language switcher
  • Compare tags case-insensitively

❌ Don’t

  • Assume the list is always long or complete
  • Ignore order (first preference matters most)
  • Confuse the array with a single language string
  • Use it alone for legal geo decisions
  • Skip saving the user’s explicit language choice

Key Takeaways

Knowledge Unlocked

Five things to remember about languages

Baseline ordered preference list for i18n and Intl fallbacks.

5
Core concepts
📈 02

Order

Best first

Prefs
💬 03

First

= language

Link
📅 04

Intl

Array fallback

Format
05

Status

Baseline

Wide

❓ Frequently Asked Questions

It is a read-only Navigator property that returns an array of BCP 47 language tags for the user’s preferred languages, ordered with the most preferred first.
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 a single tag; use languages when you need 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. You can listen with window.addEventListener("languagechange", …) and re-read navigator.languages.
Not always. For privacy (reducing fingerprinting), some browsers may expose a shorter list — for example Safari often lists one language, and Chrome’s incognito mode may also limit the list.
Did you know?

MDN notes that some browsers add language-only fallbacks in the Accept-Language header (like en-US,en;q=0.9) even when navigator.languages is only ["en-US", "zh-CN"] — the header and the JS array are related, but not always identical.

Explore locks Next

Learn the Web Locks API for cross-tab coordination.

locks →

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.

8 people found this page helpful