JavaScript Permissions API: Check Browser Authorization

The JavaScript Permissions API provides a standardized way for web applications to query the current authorization status of browser features, such as geolocation, camera access, and notifications, without actively prompting the user. By utilizing the navigator.permissions.query() method, developers can determine whether a capability is already granted, denied, or awaiting user interaction, allowing applications to adapt their user interface seamlessly based on real-time permissions.

Understanding Permission States

When you query a feature using the Permissions API, the browser returns a PermissionStatus object containing a state property. This property will always be one of three values:

Querying Permission Status with JavaScript

To inspect the status of a specific API, call navigator.permissions.query() and pass a descriptor object containing the permission name. Because this method returns a Promise, it is typically handled using async/await syntax.

async function checkGeolocationPermission() {
  try {
    const status = await navigator.permissions.query({ name: 'geolocation' });
    
    switch (status.state) {
      case 'granted':
        console.log('Location access is already allowed.');
        break;
      case 'prompt':
        console.log('User will be prompted when location is requested.');
        break;
      case 'denied':
        console.log('Location access has been blocked by the user.');
        break;
    }
  } catch (error) {
    console.error('Permission query failed or is unsupported:', error);
  }
}

checkGeolocationPermission();

Listening for Permission State Changes

A user can revoke or grant permissions at any time via the browser’s site settings. The PermissionStatus object inherits from EventTarget, enabling you to listen for dynamic state transitions via the change event.

async function monitorCameraPermission() {
  try {
    const status = await navigator.permissions.query({ name: 'camera' });

    status.onchange = () => {
      console.log(`Camera permission changed to: ${status.state}`);
      // Update UI elements dynamically
    };
  } catch (error) {
    console.error('Unable to monitor camera permission:', error);
  }
}

Common Permission Descriptors

Different browser capabilities use distinct permission names within the query object:

Best Practices

  1. Feature Detection: Always verify that navigator.permissions is supported before calling it.
  2. Context-Aware Requests: Check for the prompt state to present explanatory UI to users before triggering the browser’s native prompt.
  3. Graceful Degradation: When a state is denied, disable related UI elements and provide clear fallback instructions so users understand why the feature is unavailable.