📌 What is navigator?
The navigator object provides information about the browser, device, and user environment.
👉 It is part of the BOM and accessed via window.navigator.
window.navigator === navigator // true🧩 Common navigator Properties
1️⃣ navigator.userAgent
console.log(navigator.userAgent);Explanation:
Returns a string containing browser, OS, and device details.
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/142.0.0.0 Safari/537.362️⃣ navigator.platform
console.log(navigator.platform);Explanation:
Returns the operating system platform.
MacIntel3️⃣ navigator.language
console.log(navigator.language);Explanation:
Returns the browser’s default language.
en-US4️⃣ navigator.languages
console.log(navigator.languages);Explanation:
Returns an array of preferred languages.
["en-US", "en"]5️⃣ navigator.onLine
console.log(navigator.onLine);Explanation:
Checks whether the browser is online or offline.
true<div class="infographic-navigatorprops">
<style>
.infographic-navigatorprops {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--good: #1a8a5f;
--good-soft: #e1f2ea;
--warn: #b8860b;
--warn-soft: #fbf1d9;
--mono-font: 'IBM Plex Mono', monospace;
--display-font: 'Fraunces', Georgia, serif;
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
font-family: 'Inter', system-ui, sans-serif;
color: var(--ink);
background: var(--paper);
overflow-x: hidden;
}
.infographic-navigatorprops[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--good: #4fbf8f;
--good-soft: #16281f;
--warn: #d4a94a;
--warn-soft: #332a12;
}
.infographic-navigatorprops * { box-sizing: border-box; }
.infographic-navigatorprops h1 { font-family: var(--display-font); font-weight: 600; margin: 0; }
.infographic-navigatorprops p { margin: 0; }
.infographic-navigatorprops button { font-family: inherit; }
.np-icon { width: 1em; height: 1em; display: inline-block; vertical-align: -0.15em; stroke: currentColor; flex-shrink: 0; }
.np-wrap { padding: clamp(1.25rem, 5vw, 2.5rem) clamp(1.1rem, 5vw, 3rem) 2rem; }
.np-hero { text-align: center; margin-bottom: 1.2rem; }
.np-hero h1 { font-size: clamp(1.3rem, 4.5vw, 1.8rem); }
.np-hero p { color: var(--ink-soft); margin-top: 0.4rem; font-size: 0.86rem; }
.np-proptable { max-width: 560px; margin: 0 auto 1rem; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; }
.np-proprow { display: flex; align-items: center; gap: 0.6rem; padding: 0.65rem 0.9rem; border-top: 1px solid var(--line); cursor: pointer; transition: background 0.15s ease; }
.np-proprow:first-child { border-top: none; }
.np-proprow:hover { background: var(--accent-soft); }
.np-proprow.is-active { background: var(--accent-soft); }
.np-prop-name { font-family: var(--mono-font); font-size: 0.78rem; font-weight: 700; color: var(--accent); min-width: 148px; }
.np-prop-desc { font-size: 0.76rem; color: var(--ink-soft); flex: 1; }
.np-prop-warn { color: var(--warn); flex-shrink: 0; }
.np-online-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--ink-soft); }
.np-online-dot.is-online { background: var(--good); }
.np-online-dot.is-offline { background: var(--warn); }
.np-detail { max-width: 620px; margin: 0 auto 0.5rem; text-align: center; background: var(--paper-alt); border-left: 3px solid var(--accent); border-radius: 4px; padding: 0.85rem 1rem; }
.np-detail-code { font-family: var(--mono-font); font-size: 0.78rem; color: var(--ink); margin-bottom: 0.4rem; }
.np-detail-desc { font-size: 0.78rem; color: var(--ink-soft); margin-bottom: 0.55rem; }
.np-detail-out { font-family: var(--mono-font); font-size: 0.78rem; color: var(--good); font-weight: 700; word-break: break-word; }
.np-detail-caution { margin-top: 0.55rem; font-size: 0.72rem; color: var(--warn); display: flex; align-items: center; justify-content: center; gap: 0.35rem; }
.np-note { text-align: center; font-size: 0.8rem; color: var(--ink-soft); padding-top: 1.3rem; max-width: 580px; margin: 0 auto; }
.np-note strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-navigatorprops *, .infographic-navigatorprops *::before, .infographic-navigatorprops *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="np-wrap">
<div class="np-proptable" id="npTable">
<div class="np-proprow is-active" data-prop="userAgent">
<span class="np-prop-name">navigator.userAgent</span>
<span class="np-prop-desc">browser, OS & device string</span>
<svg class="np-icon np-prop-warn" viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>
</div>
<div class="np-proprow" data-prop="platform">
<span class="np-prop-name">navigator.platform</span>
<span class="np-prop-desc">operating system platform</span>
</div>
<div class="np-proprow" data-prop="language">
<span class="np-prop-name">navigator.language</span>
<span class="np-prop-desc">browser's default language</span>
</div>
<div class="np-proprow" data-prop="languages">
<span class="np-prop-name">navigator.languages</span>
<span class="np-prop-desc">preferred languages, in order</span>
</div>
<div class="np-proprow" data-prop="onLine">
<span class="np-prop-name">navigator.onLine</span>
<span class="np-prop-desc">connected right now?</span>
<span class="np-online-dot" id="npOnlineDot"></span>
</div>
</div>
<div class="np-detail" id="npDetail">
<div class="np-detail-code">console.log(<span id="npDetailProp">navigator.userAgent</span>);</div>
<div class="np-detail-desc" id="npDetailDesc">Returns a string containing browser, OS, and device details.</div>
<div class="np-detail-out" id="npDetailOut">reading…</div>
<div class="np-detail-caution" id="npDetailCaution" style="display:none;">
<svg class="np-icon" viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>
User agent can be spoofed → not 100% reliable.
</div>
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-navigatorprops')
|| document.querySelector('.infographic-navigatorprops');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const DESC = {
userAgent: 'Returns a string containing browser, OS, and device details.',
platform: 'Returns the operating system platform.',
language: "Returns the browser's default language.",
languages: 'Returns an array of preferred languages.',
onLine: 'Checks whether the browser is online or offline.'
};
function readValue(prop) {
try {
if (prop === 'userAgent') return '"' + navigator.userAgent + '"';
if (prop === 'platform') return '"' + (navigator.platform || 'unavailable') + '"';
if (prop === 'language') return '"' + navigator.language + '"';
if (prop === 'languages') return '[' + navigator.languages.map(l => '"' + l + '"').join(', ') + ']';
if (prop === 'onLine') return navigator.onLine ? 'true' : 'false';
} catch (e) {
return '(not readable in this context)';
}
}
const rows = wrapper.querySelectorAll('.np-proprow');
const detailProp = wrapper.querySelector('#npDetailProp');
const detailDesc = wrapper.querySelector('#npDetailDesc');
const detailOut = wrapper.querySelector('#npDetailOut');
const detailCaution = wrapper.querySelector('#npDetailCaution');
function select(prop) {
rows.forEach(r => r.classList.toggle('is-active', r.dataset.prop === prop));
detailProp.textContent = 'navigator.' + prop;
detailDesc.textContent = DESC[prop];
detailOut.textContent = readValue(prop);
detailCaution.style.display = prop === 'userAgent' ? 'flex' : 'none';
}
rows.forEach(row => row.addEventListener('click', () => select(row.dataset.prop)));
const onlineDot = wrapper.querySelector('#npOnlineDot');
function updateOnlineDot() {
onlineDot.classList.toggle('is-online', navigator.onLine);
onlineDot.classList.toggle('is-offline', !navigator.onLine);
const activeRow = wrapper.querySelector('.np-proprow.is-active');
if (activeRow && activeRow.dataset.prop === 'onLine') {
detailOut.textContent = readValue('onLine');
}
}
window.addEventListener('online', updateOnlineDot);
window.addEventListener('offline', updateOnlineDot);
updateOnlineDot();
select('userAgent');
})();
</script>🌐 Browser Capabilities
6️⃣ Cookies Enabled
console.log(navigator.cookieEnabled);Explanation:
Checks if cookies are allowed.
true7️⃣ Java Enabled (Legacy)
console.log(navigator.javaEnabled());Explanation:
Checks if Java is enabled (mostly obsolete now).
false<div class="infographic-navcapabilities">
<style>
.infographic-navcapabilities {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--good: #1a8a5f;
--good-soft: #e1f2ea;
--error: #c0392b;
--error-soft: #fbe9e7;
--mono-font: 'IBM Plex Mono', monospace;
--display-font: 'Fraunces', Georgia, serif;
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
font-family: 'Inter', system-ui, sans-serif;
color: var(--ink);
background: var(--paper);
overflow-x: hidden;
}
.infographic-navcapabilities[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--good: #4fbf8f;
--good-soft: #16281f;
--error: #e57373;
--error-soft: #3a2222;
}
.infographic-navcapabilities * { box-sizing: border-box; }
.infographic-navcapabilities h1 { font-family: var(--display-font); font-weight: 600; margin: 0; }
.infographic-navcapabilities p { margin: 0; }
.infographic-navcapabilities button { font-family: inherit; }
.nc-icon { width: 1em; height: 1em; display: inline-block; vertical-align: -0.15em; stroke: currentColor; flex-shrink: 0; }
.nc-wrap { padding: clamp(1.25rem, 5vw, 2.5rem) clamp(1.1rem, 5vw, 3rem) 2rem; }
.nc-hero { text-align: center; margin-bottom: 1.3rem; }
.nc-hero h1 { font-size: clamp(1.3rem, 4.5vw, 1.75rem); }
.nc-hero p { color: var(--ink-soft); margin-top: 0.4rem; font-size: 0.86rem; }
.nc-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.nc-card { background: var(--paper); padding: 1.1rem 1rem 1.3rem; text-align: center; display: flex; flex-direction: column; }
.nc-card-title { font-family: var(--mono-font); font-weight: 700; font-size: 0.82rem; color: var(--accent); margin-bottom: 0.5rem; }
.nc-code { background: #1e1e1e; color: #d4d4d4; border-radius: 5px; padding: 0.55rem 0.7rem; font-family: var(--mono-font); font-size: 0.68rem; margin-bottom: 0.7rem; text-align: left; }
.tok-fn { color: #dcdcaa; }
.tok-punc { color: #d4d4d4; }
.tok-var { color: #9cdcfe; }
.nc-card-desc { font-size: 0.78rem; color: var(--ink-soft); margin-bottom: 0.9rem; line-height: 1.45; min-height: 3em; }
.nc-check-btn { border: none; background: var(--accent); color: #fff; padding: 0.44rem 0.8rem; font-size: 0.76rem; font-weight: 600; border-radius: 5px; cursor: pointer; margin-bottom: 0.8rem; }
.nc-check-btn:active { transform: scale(0.96); }
.nc-badge { margin-top: auto; display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem; border: 1.5px dashed var(--line); border-radius: 6px; padding: 0.5rem 0.8rem; font-family: var(--mono-font); font-size: 0.8rem; color: var(--ink-soft); transition: border-color 0.25s ease, background 0.25s ease, color 0.25s ease; }
.nc-badge.is-true { border-style: solid; border-color: var(--good); background: var(--good-soft); color: var(--good); font-weight: 700; }
.nc-badge.is-false { border-style: solid; border-color: var(--error); background: var(--error-soft); color: var(--error); font-weight: 700; }
.nc-badge .nc-icon { width: 14px; height: 14px; }
.nc-legacy-tag { font-family: var(--mono-font); font-size: 0.62rem; color: var(--ink-soft); background: var(--paper-alt); border-radius: 4px; padding: 0.15rem 0.4rem; display: inline-block; margin-bottom: 0.5rem; }
@media (max-width: 560px) {
.nc-cards { grid-template-columns: 1fr; }
}
.nc-note { text-align: center; font-size: 0.8rem; color: var(--ink-soft); padding-top: 1.3rem; max-width: 520px; margin: 0 auto; }
.nc-note strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-navcapabilities *, .infographic-navcapabilities *::before, .infographic-navcapabilities *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="nc-wrap">
<div class="nc-cards">
<div class="nc-card">
<div class="nc-card-title">Cookies Enabled</div>
<div class="nc-code"><span class="tok-var">console</span><span class="tok-punc">.</span><span class="tok-fn">log</span><span class="tok-punc">(</span><span class="tok-var">navigator</span><span class="tok-punc">.</span><span class="tok-var">cookieEnabled</span><span class="tok-punc">);</span></div>
<div class="nc-card-desc">Checks if cookies are allowed in this browser.</div>
<button class="nc-check-btn" id="ncCookieBtn" type="button">check now</button>
<div class="nc-badge" id="ncCookieBadge">not checked yet</div>
</div>
<div class="nc-card">
<div class="nc-card-title">Java Enabled</div>
<div class="nc-legacy-tag">legacy — mostly obsolete</div>
<div class="nc-code"><span class="tok-var">console</span><span class="tok-punc">.</span><span class="tok-fn">log</span><span class="tok-punc">(</span><span class="tok-var">navigator</span><span class="tok-punc">.</span><span class="tok-fn">javaEnabled</span><span class="tok-punc">());</span></div>
<div class="nc-card-desc">Checks if the Java plugin is enabled. No modern browser ships one anymore.</div>
<button class="nc-check-btn" id="ncJavaBtn" type="button">check now</button>
<div class="nc-badge" id="ncJavaBadge">not checked yet</div>
</div>
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-navcapabilities')
|| document.querySelector('.infographic-navcapabilities');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
function setBadge(el, value) {
el.classList.remove('is-true', 'is-false');
el.classList.add(value ? 'is-true' : 'is-false');
const checkIcon = '<svg class="nc-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>';
const xIcon = '<svg class="nc-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>';
el.innerHTML = (value ? checkIcon : xIcon) + ' ' + value;
}
wrapper.querySelector('#ncCookieBtn').addEventListener('click', () => {
let enabled = false;
try { enabled = navigator.cookieEnabled; } catch (e) { enabled = false; }
setBadge(wrapper.querySelector('#ncCookieBadge'), enabled);
});
wrapper.querySelector('#ncJavaBtn').addEventListener('click', () => {
let enabled = false;
try { enabled = typeof navigator.javaEnabled === 'function' ? navigator.javaEnabled() : false; } catch (e) { enabled = false; }
setBadge(wrapper.querySelector('#ncJavaBadge'), enabled);
});
})();
</script>📍 Location & Device APIs
8️⃣ Geolocation
navigator.geolocation.getCurrentPosition(
position => {
console.log(position.coords.latitude, position.coords.longitude);
},
error => {
console.log("Permission denied");
}
);Explanation:
Gets user’s location
Requires user permission
Works only on HTTPS
22.5726 88.36399️⃣ Clipboard Access
navigator.clipboard.readText().then(text => {
console.log(text);
});Explanation:
Reads text from clipboard (permission required).
Copied text<div class="infographic-navsensitive">
<style>
.infographic-navsensitive {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--good: #1a8a5f;
--good-soft: #e1f2ea;
--error: #c0392b;
--error-soft: #fbe9e7;
--mono-font: 'IBM Plex Mono', monospace;
--display-font: 'Fraunces', Georgia, serif;
box-sizing: border-box;
max-width: 880px;
margin: 0 auto;
font-family: 'Inter', system-ui, sans-serif;
color: var(--ink);
background: var(--paper);
overflow-x: hidden;
}
.infographic-navsensitive[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--good: #4fbf8f;
--good-soft: #16281f;
--error: #e57373;
--error-soft: #3a2222;
}
.infographic-navsensitive * { box-sizing: border-box; }
.infographic-navsensitive h1 { font-family: var(--display-font); font-weight: 600; margin: 0; }
.infographic-navsensitive p { margin: 0; }
.infographic-navsensitive button { font-family: inherit; }
.ns-icon { width: 1em; height: 1em; display: inline-block; vertical-align: -0.15em; stroke: currentColor; flex-shrink: 0; }
.ns-wrap { padding: clamp(1.25rem, 5vw, 2.5rem) clamp(1.1rem, 5vw, 3rem) 2rem; }
.ns-hero { text-align: center; margin-bottom: 1.2rem; }
.ns-hero h1 { font-size: clamp(1.3rem, 4.5vw, 1.75rem); }
.ns-hero p { color: var(--ink-soft); margin-top: 0.4rem; font-size: 0.86rem; max-width: 480px; margin-left: auto; margin-right: auto; }
.ns-tabs { display: flex; border: 1px solid var(--line); border-radius: 6px 6px 0 0; overflow: hidden; }
.ns-tab { flex: 1; display: flex; align-items: center; justify-content: center; gap: 0.4rem; background: var(--paper-alt); color: var(--ink-soft); border: none; border-right: 1px solid var(--line); padding: 0.7rem 0.5rem; font-family: var(--mono-font); font-size: 0.76rem; font-weight: 700; cursor: pointer; transition: background 0.2s ease, color 0.2s ease; }
.ns-tab:last-child { border-right: none; }
.ns-tab .ns-icon { width: 15px; height: 15px; }
.ns-tab.is-active { background: var(--accent-soft); color: var(--accent); }
.ns-panel-frame { border: 1px solid var(--line); border-top: none; border-radius: 0 0 8px 8px; padding: 1.2rem clamp(1rem, 4vw, 1.6rem) 1.4rem; text-align: center; }
.ns-panel { display: none; }
.ns-panel.is-active { display: block; }
.ns-code { background: #1e1e1e; color: #d4d4d4; border-radius: 5px; padding: 0.6rem 0.7rem; font-family: var(--mono-font); font-size: 0.66rem; line-height: 1.5; white-space: pre; overflow-x: auto; margin-bottom: 0.9rem; text-align: left; max-width: 420px; margin-left: auto; margin-right: auto; }
.tok-kw { color: #569cd6; }
.tok-fn { color: #dcdcaa; }
.tok-str { color: #ce9178; }
.tok-var { color: #9cdcfe; }
.tok-punc { color: #d4d4d4; }
.tok-prop { color: #9cdcfe; }
.ns-call-btn { border: none; background: var(--accent); color: #fff; padding: 0.46rem 0.85rem; font-size: 0.76rem; font-weight: 600; border-radius: 5px; cursor: pointer; margin-bottom: 0.9rem; }
.ns-call-btn:active { transform: scale(0.96); }
/* --- mock permission prompt --- */
.ns-mockscreen { border: 1.5px solid var(--line); border-radius: 8px; background: var(--paper-alt); padding: 1.2rem 0.8rem; min-height: 96px; display: flex; align-items: center; justify-content: center; margin-bottom: 0; }
.ns-mockscreen-empty { color: var(--ink-soft); font-size: 0.76rem; font-style: italic; }
.ns-permit { background: var(--paper); border: 1.5px solid var(--line); border-radius: 6px; padding: 0.8rem 0.9rem; box-shadow: 0 4px 14px rgba(0,0,0,0.15); max-width: 260px; opacity: 0; transform: scale(0.9); transition: opacity 0.2s ease, transform 0.2s ease; }
.ns-permit.is-shown { opacity: 1; transform: scale(1); }
.ns-permit-msg { font-size: 0.76rem; margin-bottom: 0.65rem; text-align: left; line-height: 1.4; color: var(--ink); }
.ns-permit-msg strong { display: block; font-size: 0.72rem; color: var(--ink-soft); margin-bottom: 0.2rem; }
.ns-permit-actions { display: flex; gap: 0.5rem; justify-content: center; }
.ns-permit-btn { flex: 1; border: 1px solid var(--line); background: var(--paper); color: var(--ink); padding: 0.35rem 0.5rem; font-size: 0.72rem; font-weight: 600; border-radius: 4px; cursor: pointer; }
.ns-permit-btn.ns-allow { background: var(--accent); color: #fff; border-color: var(--accent); }
.ns-outbox { margin-top: 0.8rem; font-family: var(--mono-font); font-size: 0.78rem; border-radius: 5px; padding: 0.55rem 0.7rem; min-height: 1.5em; transition: background 0.2s ease, color 0.2s ease; background: #1e1e1e; color: #6b6b6b; }
.ns-outbox.is-good { color: #4fbf8f; }
.ns-outbox.is-error { color: #e57373; }
.ns-note { text-align: center; font-size: 0.8rem; color: var(--ink-soft); padding-top: 1.3rem; max-width: 560px; margin: 0 auto; }
.ns-note strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-navsensitive *, .infographic-navsensitive *::before, .infographic-navsensitive *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ns-wrap">
<div class="ns-tabs" id="nsTabs">
<button class="ns-tab is-active" data-tab="geo" type="button">
<svg class="ns-icon" viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/></svg>
Geolocation
</button>
<button class="ns-tab" data-tab="clipboard" type="button">
<svg class="ns-icon" viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="8" height="4" x="8" y="2" rx="1" ry="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/></svg>
Clipboard Access
</button>
</div>
<div class="ns-panel-frame">
<div class="ns-panel is-active" data-panel="geo">
<div class="ns-code"><span class="tok-var">navigator</span><span class="tok-punc">.</span><span class="tok-prop">geolocation</span><span class="tok-punc">.</span><span class="tok-fn">getCurrentPosition</span><span class="tok-punc">(</span>
<span class="tok-var">position</span> <span class="tok-punc">=> {</span>
<span class="tok-var">console</span><span class="tok-punc">.</span><span class="tok-fn">log</span><span class="tok-punc">(</span><span class="tok-var">position</span><span class="tok-punc">.</span><span class="tok-prop">coords</span><span class="tok-punc">.</span><span class="tok-prop">latitude</span><span class="tok-punc">,</span> <span class="tok-var">position</span><span class="tok-punc">.</span><span class="tok-prop">coords</span><span class="tok-punc">.</span><span class="tok-prop">longitude</span><span class="tok-punc">);</span>
<span class="tok-punc">},</span>
<span class="tok-var">error</span> <span class="tok-punc">=> {</span>
<span class="tok-var">console</span><span class="tok-punc">.</span><span class="tok-fn">log</span><span class="tok-punc">(</span><span class="tok-str">"Permission denied"</span><span class="tok-punc">);</span>
<span class="tok-punc">}</span>
<span class="tok-punc">);</span></div>
<button class="ns-call-btn" id="nsGeoBtn" type="button">call getCurrentPosition()</button>
<div class="ns-mockscreen" id="nsGeoScreen"><span class="ns-mockscreen-empty">// waiting</span></div>
<div class="ns-outbox" id="nsGeoOut">console —</div>
</div>
<div class="ns-panel" data-panel="clipboard">
<div class="ns-code"><span class="tok-var">navigator</span><span class="tok-punc">.</span><span class="tok-prop">clipboard</span><span class="tok-punc">.</span><span class="tok-fn">readText</span><span class="tok-punc">().</span><span class="tok-fn">then</span><span class="tok-punc">(</span><span class="tok-var">text</span> <span class="tok-punc">=> {</span>
<span class="tok-var">console</span><span class="tok-punc">.</span><span class="tok-fn">log</span><span class="tok-punc">(</span><span class="tok-var">text</span><span class="tok-punc">);</span>
<span class="tok-punc">});</span></div>
<button class="ns-call-btn" id="nsClipBtn" type="button">call clipboard.readText()</button>
<div class="ns-mockscreen" id="nsClipScreen"><span class="ns-mockscreen-empty">// waiting</span></div>
<div class="ns-outbox" id="nsClipOut">console —</div>
</div>
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-navsensitive')
|| document.querySelector('.infographic-navsensitive');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const tabs = wrapper.querySelectorAll('.ns-tab');
const panels = wrapper.querySelectorAll('.ns-panel');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
tabs.forEach(t => t.classList.remove('is-active'));
panels.forEach(p => p.classList.remove('is-active'));
tab.classList.add('is-active');
wrapper.querySelector('.ns-panel[data-panel="' + tab.dataset.tab + '"]').classList.add('is-active');
});
});
function showPermit(screenEl, message, onAllow, onBlock) {
screenEl.innerHTML = '<div class="ns-permit"><div class="ns-permit-msg"><strong>codeveda.dev wants to</strong>' + message + '</div><div class="ns-permit-actions"><button class="ns-permit-btn" data-act="block">Block</button><button class="ns-permit-btn ns-allow" data-act="allow">Allow</button></div></div>';
const permit = screenEl.querySelector('.ns-permit');
requestAnimationFrame(() => permit.classList.add('is-shown'));
permit.querySelector('[data-act="allow"]').addEventListener('click', () => {
screenEl.innerHTML = '<span class="ns-mockscreen-empty">// allowed</span>';
onAllow();
});
permit.querySelector('[data-act="block"]').addEventListener('click', () => {
screenEl.innerHTML = '<span class="ns-mockscreen-empty">// blocked</span>';
onBlock();
});
}
const geoScreen = wrapper.querySelector('#nsGeoScreen');
const geoOut = wrapper.querySelector('#nsGeoOut');
wrapper.querySelector('#nsGeoBtn').addEventListener('click', () => {
geoOut.className = 'ns-outbox';
geoOut.textContent = 'console — waiting for permission…';
showPermit(
geoScreen,
' know your location',
() => { geoOut.className = 'ns-outbox is-good'; geoOut.textContent = '22.5726 88.3639'; },
() => { geoOut.className = 'ns-outbox is-error'; geoOut.textContent = 'Permission denied'; }
);
});
const clipScreen = wrapper.querySelector('#nsClipScreen');
const clipOut = wrapper.querySelector('#nsClipOut');
wrapper.querySelector('#nsClipBtn').addEventListener('click', () => {
clipOut.className = 'ns-outbox';
clipOut.textContent = 'console — waiting for permission…';
showPermit(
clipScreen,
' see text you copied',
() => { clipOut.className = 'ns-outbox is-good'; clipOut.textContent = 'Copied text'; },
() => { clipOut.className = 'ns-outbox is-error'; clipOut.textContent = 'NotAllowedError: permission denied'; }
);
});
})();
</script>🧠 Feature Detection
if ("geolocation" in navigator) {
console.log("Geolocation supported");
}Explanation:
Checks if a feature is supported before using it.
Geolocation supported🆚 navigator Use Cases
Use Case | Example |
|---|---|
Detect language | Localization |
Online status | Offline apps |
Device info | Adaptive UI |
Permissions | Location, clipboard |
⭐ Important Notes
Info can be inaccurate or spoofed
Do feature detection, not browser detection
Many APIs need user permission
✅ Summary
navigatorgives browser & device infoUsed for feature detection and environment checks
Part of BOM, under
window