In short
The JavaScript navigator object tells your code about the user's browser and device: their language, whether they are online, and which features are available. You will also learn why feature detection beats userAgent checks. What is the navigator object?
The JavaScript navigator object tells your code about the user's browser and device: their language, whether they are online, and which features are available. You will also learn why feature detection beats userAgent checks.
What is the navigator object?
window.navigator (or just navigator) is like the browser's ID card. It holds facts about the browser and device, and it is also the home of several modern device features, such as the clipboard, location and sharing.
console.log(navigator.language); // Output (example): en-GB
console.log(navigator.languages); // Output (example): ["en-GB", "en", "de"]
console.log(navigator.onLine); // Output (example): true
console.log(navigator.cookieEnabled); // Output (example): true
console.log(navigator.hardwareConcurrency); // Output (example): 8 (CPU cores)
Here is a quick reference of the most useful parts:
| Property / method | What it gives you |
|---|---|
navigator.language | The user's preferred language, like "en-US" |
navigator.languages | All preferred languages, best first |
navigator.onLine | true if the browser thinks it has a network connection |
navigator.cookieEnabled | true if cookies are allowed |
navigator.userAgent | A long text string that describes the browser (avoid relying on it) |
navigator.clipboard | Copy and paste text (async) |
navigator.geolocation | The user's location, with permission |
navigator.share() | Opens the device's native share menu |
How to detect the user's language with navigator.language
navigator.language gives a language tag: a language code, sometimes followed by a region, like "en-US" (English, United States) or "pt-BR" (Portuguese, Brazil). navigator.languages is a list in the order the user chose in their browser settings.
A practical use is choosing a greeting or formatting dates and numbers in the user's style:
const greetings = { en: "Welcome!", es: "¡Bienvenido!", de: "Willkommen!", fr: "Bienvenue !" };
// Find the first language the user prefers that we support
const userLang = navigator.languages
.map((tag) => tag.split("-")[0]) // "en-GB" -> "en"
.find((code) => greetings[code]) ?? "en"; // fallback to English
console.log(greetings[userLang]);
// Output (for an English browser): Welcome!
const price = new Intl.NumberFormat(navigator.language, {
style: "currency",
currency: "EUR"
}).format(1234.5);
console.log(price);
// Output (en-GB): €1,234.50 (de-DE): 1.234,50 €
split("-")[0] keeps only the language part. find picks the first one we have a greeting for, and ?? "en" covers users whose languages we do not support. Intl.NumberFormat uses the language tag to format numbers the local way, with the right separators.
Tip: Use the browser language as a smart default, but always let users change the language themselves. Many people use a browser set to a language they do not prefer, for example on a work computer.
How to detect online and offline status
navigator.onLine is true or false, and the online and offline events on window fire when it changes. This is great for showing a friendly warning:
<!DOCTYPE html>
<html lang="en">
<body>
<p id="status"></p>
<script>
const statusText = document.querySelector("#status");
const updateStatus = () => {
if (navigator.onLine) {
statusText.textContent = "You are online.";
statusText.style.color = "green";
} else {
statusText.textContent = "You are offline. Changes will be saved when you reconnect.";
statusText.style.color = "crimson";
}
};
updateStatus(); // check once on load
window.addEventListener("online", updateStatus);
window.addEventListener("offline", updateStatus);
</script>
</body>
</html>
Open the page, then open DevTools, go to the Network tab and choose Offline from the throttling menu. The text turns red immediately. Switch back and it turns green again.
Note:
onLinebeingtrueonly means the device is connected to a network, like home Wi-Fi. It does not promise the internet or your server actually works.falseis reliable;truemeans "probably". When afetchfails, handle the error anyway.
Why feature detection beats userAgent sniffing
navigator.userAgent is a long string like "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/... Safari/537.36". Notice that Chrome claims to be Mozilla, AppleWebKit and Safari. For historical reasons, almost every browser pretends to be the others, and modern browsers also hide or freeze parts of this string for privacy.
Checking this string to decide what your code does is called user agent sniffing, and it breaks easily: new browsers appear, versions change, and users can fake it. The better way is feature detection: simply check whether the feature you need exists.
// Bad: guessing from the browser name
if (navigator.userAgent.includes("Chrome")) {
// Edge, Opera, Brave and Samsung Internet also include "Chrome"!
}
// Good: checking for the feature itself
if ("share" in navigator) {
console.log("Native sharing is available");
} else {
console.log("Use a fallback");
}
if ("clipboard" in navigator) {
console.log("Clipboard API available");
}
// Output (desktop Chrome, example):
// Use a fallback
// Clipboard API available
The "feature" in object check returns true or false and never crashes. It answers the real question ("can I use this?") instead of guessing from a name.
Common mistake: Writing
if (navigator.userAgent.includes("Safari"))to target Safari. Chrome on desktop and almost every Android browser also contain "Safari" in their user agent.
Clipboard, geolocation and sharing: navigator's device features
The navigator object is where several powerful device features live. You will study the clipboard and geolocation in detail in the Useful Browser APIs lesson, so here is just a quick overview:
navigator.clipboard.writeText(text)copies text and returns a Promise. It needs a secure page (HTTPS) and usually a user action like a click.navigator.geolocation.getCurrentPosition(success, error)asks for the user's location. The browser always asks permission first.navigator.share(data)opens the phone's or computer's native share sheet (WhatsApp, email, and so on).
Let's build a share button that uses navigator.share when it exists and falls back to copying the link:
<!DOCTYPE html>
<html lang="en">
<body>
<h1>10 Easy Pasta Recipes</h1>
<button id="shareBtn">Share this recipe</button>
<p id="message"></p>
<script>
const shareBtn = document.querySelector("#shareBtn");
const message = document.querySelector("#message");
shareBtn.addEventListener("click", async () => {
const shareData = {
title: document.title || "10 Easy Pasta Recipes",
text: "Look at these quick pasta recipes!",
url: location.href
};
if (navigator.share) {
try {
await navigator.share(shareData); // opens the native share menu
message.textContent = "Thanks for sharing!";
} catch (error) {
// The user closed the menu: this is not a real problem
if (error.name !== "AbortError") message.textContent = "Sharing failed.";
}
} else if (navigator.clipboard) {
await navigator.clipboard.writeText(shareData.url);
message.textContent = "Link copied to clipboard!";
} else {
message.textContent = `Copy this link: ${shareData.url}`;
}
});
</script>
</body>
</html>
On a phone, clicking the button opens the native share menu. On a desktop browser without sharing support, the link is copied and you see "Link copied to clipboard!". On a very old browser, the link is simply shown. await waits for the share menu to close; if the user cancels it, the browser throws an AbortError, which we quietly ignore. You can read more on MDN's Navigator page.
Practice exercise
Create a small "about your browser" panel. Show the user's top language, a list of all their languages, whether they are online (and update it with the online and offline events), and three lines that say "Supported" or "Not supported" for share, clipboard and geolocation using feature detection.
Hint: loop over ["share", "clipboard", "geolocation"] and use feature in navigator to build each line.
Key takeaways
navigatordescribes the browser and device and holds features like clipboard, geolocation and share.navigator.languageandnavigator.languagesgive smart defaults for language and formatting; still let users choose.navigator.onLineplus theonlineandofflineevents let you show connection warnings;falseis reliable,truemeans "probably".- Avoid
userAgentsniffing; use feature detection like"share" in navigator. - Always give a fallback when a device feature is missing.