navigator.permissions is a read-only property that returns a Permissions object — the entry point to the Permissions API. Learn query(), the granted / prompt / denied states, MDN’s geolocation example, change listeners, five examples, and try-it labs.
01
Kind
Read-only property
02
Returns
Permissions
03
Baseline
Widely available
04
Main method
query()
05
States
granted · prompt · denied
06
Use
Permission-aware UX
Fundamentals
Introduction
Powerful browser features — location, camera, notifications, and more — need user permission. Calling those APIs blindly can surprise users with prompts or fail silently after a denial.
navigator.permissions gives you a Permissions object so you can ask what the status is before (or after) you request a feature. MDN’s classic example checks geolocation and only shows a map when access is granted.
💡
Query is not always a request
permissions.query() reports the current status. The browser usually shows a permission prompt when you call the feature API itself (for example getCurrentPosition). Design UX for all three states.
Concept
Understanding the permissions Property
Reading navigator.permissions does not return a Boolean. It returns a Permissions object. From there you call query({ name: "..." }) and get a PermissionStatus whose state is one of:
granted — permission is allowed; you can use the feature.
prompt — the browser may ask the user when you request it.
denied — blocked; offer an alternative path, do not nag.
Read-only entry point — you do not assign to navigator.permissions.
Baseline — Widely available (MDN, since September 2022).
Foundation
📝 Syntax
General form of the property:
JavaScript
navigator.permissions
Value
A Permissions object used to query permission status.
Common patterns
JavaScript
// Feature-detect, then query (MDN-style):
if (navigator.permissions) {
navigator.permissions.query({ name: "geolocation" }).then((result) => {
if (result.state === "granted") {
// showMap();
} else if (result.state === "prompt") {
// showButtonToEnableMap();
}
// Do nothing special if denied.
});
}
prompt — showButtonToEnableMap()
(or granted / denied depending on your site settings)
How It Works
This mirrors MDN’s example with async/await and a clear message for each state.
📈 Practical Patterns
Handle all states, listen for changes, and query safely.
Example 3 — Map Every State to UX Copy
Build a short status string for a settings or map panel.
JavaScript
async function geoStatusMessage() {
if (!navigator.permissions) return "Permissions API not available";
const { state } = await navigator.permissions.query({ name: "geolocation" });
const messages = {
granted: "Location allowed — you can show the map.",
prompt: "Location not decided yet — show an Enable button.",
denied: "Location blocked — explain how to re-enable in settings."
};
return messages[state] || ("Unknown state: " + state);
}
geoStatusMessage().then((msg) => console.log(msg));
navigator.permissions is Baseline Widely available across modern browsers (MDN: since September 2022). Individual permission names can still differ — feature-detect and catch query errors.
✓ Baseline · Widely available
Navigator.permissions
Query permission status for permission-aware UX. Pair with the real feature API (geolocation, media, and so on) when you need the capability itself.
UniversalWidely available
Google ChromeFull support · Desktop & Mobile
Full support
Mozilla FirefoxFull support · Desktop & Mobile
Full support
Apple SafariFull support · modern Safari
Full support
Microsoft EdgeFull support · Chromium
Full support
OperaFull support · Modern versions
Full support
Internet ExplorerNot a Baseline target for Permissions API
Unavailable
permissionsExcellent
Bottom line: Detect navigator.permissions, query safely, branch on granted/prompt/denied, and never nag after denial.
Wrap Up
Conclusion
navigator.permissions is the Baseline entry point to the Permissions API. Query status with query(), branch on granted / prompt / denied, listen for change when helpful, and call the real feature API only when your UX is ready.
Assume every permission name works in every browser
Treat query() as a substitute for the feature API
Try to assign to navigator.permissions
Hide critical flows behind a single permission without a fallback
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about permissions
Baseline Permissions entry point — query, then branch UX.
5
Core concepts
🔒01
Returns
Permissions
Type
🔎02
Method
query()
API
🎯03
States
granted / prompt / denied
UX
🔁04
Events
status change
Live
✅05
Status
Baseline
Modern
❓ Frequently Asked Questions
It is a read-only Navigator property that returns a Permissions object — the entry point to the Permissions API for querying (and in some cases updating) permission status for covered browser features.
No. MDN marks navigator.permissions as Baseline Widely available (since September 2022). It is not Deprecated, Experimental, or Non-standard.
Call navigator.permissions.query({ name: "geolocation" }) (or another supported name). It returns a Promise that resolves to a PermissionStatus with a state of granted, prompt, or denied.
granted means the feature may run without asking again. prompt means the browser may ask the user. denied means access is blocked — do not keep prompting; show an alternative UX.
Usually no — query() reports the current status. The actual request often happens when you call the feature API (for example getCurrentPosition). Always handle denial gracefully.
No. The property is read-only. You use methods on the returned Permissions object, such as query().
Did you know?
MDN’s geolocation sample deliberately does nothing when permission is denied. That is intentional UX: after a hard no, keep showing alternative content instead of opening another prompt loop.