ScreenshotNeo

BlogHow-to

Set Browser Permissions with Puppeteer

Grant and clear browser permissions in Puppeteer with BrowserContext.setPermission, including a complete geolocation example and fixes for common errors.

By the ScreenshotNeo team4 October 20266 min read

Use BrowserContext.setPermission(origin, ...permissions) to set a browser permission for a site in Puppeteer. For example, grant geolocation to https://example.com, then set a matching test location with page.setGeolocation(). The page must belong to the context whose permissions you set. The older overridePermissions() method is deprecated; use the descriptor-and-state form of setPermission() in new code.

1. Complete geolocation example

This example launches Chromium, grants geolocation to one origin, sets coordinates, visits that origin, and clears permission overrides when the work is complete. Install Puppeteer with npm install puppeteer, save this as permissions.js, then run node permissions.js.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  const context = browser.defaultBrowserContext();

  try {
    await context.setPermission('https://example.com', {
      permission: 'geolocation',
      state: 'granted',
    });

    const page = await context.newPage();
    await page.setGeolocation({ latitude: 37.7749, longitude: -122.4194 });
    await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });

    console.log('Page title:', await page.title());
  } finally {
    await context.clearPermissionOverrides();
    await browser.close();
  }
})().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

Replace the example origin and coordinates with the values your test needs. The origin is the scheme, host, and optional port; it is not a full page path. The permission grant does not itself provide a location, so geolocation tests should configure coordinates as shown.

2. Choose the right API and scope

Set a permission on a specific context

BrowserContext.setPermission(origin, ...permissions) configures permissions for a given origin in that context. Use this when you deliberately create or select a context for a test. Ensure that the page is opened from that same context.

const context = await browser.createBrowserContext();
await context.setPermission('https://example.com', {
  permission: 'geolocation',
  state: 'granted',
});
const page = await context.newPage();

Browser contexts isolate browser state, so a permission set on one context should not be assumed to apply to a page in another. Close a context created for a test when its work is done.

Use the default context shortcut

Browser.setPermission() is a shortcut for setting the permission on the browser’s default context. Use it when the page is in that context and you do not need a separately managed context.

await browser.setPermission('https://example.com', {
  permission: 'geolocation',
  state: 'granted',
});

Use descriptor and state entries

The current API accepts an origin and one or more entries with a permission descriptor and a state. The documented state values are browser permission states such as 'granted', 'denied', or 'prompt'; check the Puppeteer API reference for the accepted permissions and types in your installed version. The next API documentation also allows '*' as an origin. Prefer a specific origin for a test that should model one site’s access.

await context.setPermission('https://example.com', {
  permission: 'geolocation',
  state: 'denied',
});

Pass multiple descriptor/state entries when a scenario needs multiple permissions, following the signature and supported permission types for your Puppeteer release.

Migrate from the legacy method

Older examples use overridePermissions(origin, permissions), for example:

await context.overridePermissions('https://example.com', ['geolocation']);

This method is deprecated in the stable API reference and obsolete in the next API documentation. Replace it with setPermission() and an explicit state. The next API docs say permissions not included in the array are automatically denied; do not assume that behavior or old method semantics apply unchanged to the newer API.

3. Permission lifecycle and cleanup

clearPermissionOverrides() clears permission overrides for the entire browser context. It does not target just one permission or origin. Use it during cleanup if later tests might reuse that context and depend on normal browser permission behavior.

try {
  await context.setPermission('https://example.com', {
    permission: 'geolocation',
    state: 'granted',
  });
  // Run the test using pages created from this context.
} finally {
  await context.clearPermissionOverrides();
}

If the context exists only for one test, closing that context after the test is another clear lifecycle boundary. Keep cleanup in a finally block so it runs even when navigation or assertions fail.

4. Permission options and edge cases

  • Origin matching: Set the permission for the origin the page actually visits, including the correct scheme and port when applicable. A subdomain is a different origin from its parent domain.
  • Context matching: Set the permission on the same context that creates the page. A setting on the default context does not configure a page in a separately created context.
  • Grant versus prompt: Use 'granted' to test the allowed path, 'denied' to test rejection handling, and 'prompt' when the scenario needs the browser’s prompt behavior, subject to support in your version and browser.
  • Permission versus capability data: Granting geolocation allows the page to request location; set coordinates separately with page.setGeolocation().
  • Wildcard origin: The next API reference includes '*' in the origin type. Verify support in the Puppeteer version you run, and use a specific origin when the test is meant to constrain access.
  • Version differences: The sources do not establish a complete compatibility matrix. Consult the API reference matching your installed Puppeteer version rather than copying a signature from a different release.

5. Troubleshooting

Symptom Likely cause What to check
The site still shows a permission prompt or behaves as denied The grant was applied to a different origin or browser context than the page uses. Compare the visited page’s scheme, host, and port with the origin passed to setPermission(), and create the page with the same context.
Geolocation returns no useful position A permission grant was mistaken for the location value. Call page.setGeolocation({ latitude, longitude }) as well as granting the permission.
overridePermissions is deprecated or unavailable The code uses the legacy API against a current Puppeteer version. Move to setPermission(origin, { permission, state }) and verify the exact signature in the installed-version API reference.
Another test unexpectedly has changed permissions Overrides remain on a context reused between tests, or cleanup cleared more than expected. Use a dedicated context or call clearPermissionOverrides() at the right lifecycle boundary. It clears the entire context’s overrides.
The code rejects a permission name or descriptor The permission type or descriptor shape is not supported by that Puppeteer/browser version. Check the current API reference and installed package version; the reviewed sources do not provide a full compatibility list.

6. Reliability, speed, and cost

Permission setup is local browser configuration and does not require an extra network request. For reliable tests, set permissions before navigating, use the same context for setup and page creation, and clear overrides or close the context after the test. Choose the narrowest context and origin scope that matches the scenario so unrelated pages and tests do not inherit assumptions.

For screenshots of permission-gated pages, Puppeteer gives you control of the browser setup and test flow, but you still need to manage a browser runtime and the page’s loading behavior. If the goal is simply to capture a website image or PDF, a screenshot API can avoid maintaining that browser setup.

7. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. Make one GET request with a URL to receive a PNG, JPEG, WebP, or PDF. See the API documentation for request options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up free and capture 1,000 screenshots a month with no card.

8. FAQ

Does setting a permission change the browser’s actual system permission?

It sets the browser permission state for an origin in the selected context for automation. Keep the test scoped to that context and clean up its overrides when needed.

Can I grant permissions to every site?

The next API signature accepts '*' as an origin. Check that your installed Puppeteer version supports it, and prefer a specific origin for tests that should model a single site.

Should I use Browser.setPermission() or BrowserContext.setPermission()?

Use the context method when selecting a context explicitly. Use the browser method when the page belongs to the default context; it is a shortcut to that context’s method.

Where can I confirm the method signature?

Use the official BrowserContext.setPermission API reference and the documentation for the Puppeteer version installed in your project.

Sources