How to Use Cookies with Puppeteer
Set, read, and delete cookies with Puppeteer. Learn how browser context scope, cookie attributes, and common errors affect which pages receive them.
Puppeteer cookies belong to a browser context. Set a cookie on the same BrowserContext as the page before navigating when the page needs it on its first request; read and delete cookies through that context as well. For the default context, the browser-level cookie methods are convenient shortcuts. The complete context-scoped example is below.
1. Install Puppeteer and choose a context
Install Puppeteer in a Node.js project if it is not already installed:
npm install puppeteer
A browser context has isolated storage, including cookies and local storage. Pages created in that context, including popups, share that context’s storage. Choose the context that owns the target page before setting cookies. See the official Puppeteer cookies guide and BrowserContext reference.
2. Set a cookie before navigating
This runnable ES module creates an isolated context, sets a cookie for the intended site, visits the site, reads the context’s cookies, and removes the cookie by filter.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const context = await browser.createBrowserContext();
try {
const page = await context.newPage();
await context.setCookie({
name: 'session_hint',
value: 'example',
url: 'https://example.com',
secure: true,
httpOnly: true,
sameSite: 'Lax',
});
await page.goto('https://example.com', {
waitUntil: 'domcontentloaded',
});
const cookies = await context.cookies();
console.log(cookies);
await context.deleteMatchingCookies({ name: 'session_hint' });
} finally {
await context.close();
}
} finally {
await browser.close();
}
Save as cookies.mjs and run node cookies.mjs. This example combines documented APIs and cookie fields; check the types and reference for your installed Puppeteer version before relying on optional fields or filter shapes. Puppeteer’s current references document BrowserContext.setCookie(), cookies(), and deleteMatchingCookies(). BrowserContext API · deleteMatchingCookies API
3. Read cookies
Read cookies from the storage owner whose pages you want to inspect:
const cookies = await context.cookies();
console.log(cookies.map(({ name, value, domain, path, expires }) => ({
name, value, domain, path, expires,
})));
For work in the default browser context, Puppeteer also documents browser.cookies(). A cookie marked httpOnly is not available to page JavaScript through document.cookie; use the Puppeteer browser or context cookie API for browser-level inspection. Cookie attributes and available fields are described in the CookieData and CookieParam references.
4. Delete cookies safely
Use BrowserContext.deleteCookie() when you have the cookie details to remove, or deleteMatchingCookies() when a filter such as a name is more useful. For example:
await context.deleteMatchingCookies({ name: 'session_hint' });
For the default context, the browser-level delete methods are shortcuts. Avoid the obsolete Page.deleteCookie(); Puppeteer recommends browser or browser-context deletion APIs. See Page.deleteCookie reference.
5. Choose cookie attributes and scope
Cookie fields determine where a cookie applies and how the browser treats it. Match them to the site’s expected cookie rather than treating url, domain, and path as interchangeable.
| Field | Use |
|---|---|
url |
On CookieParam, identifies a URL from which default domain, path, and source scheme can be derived. |
domain |
Scope the cookie to the intended host or domain. Check whether the target host matches. |
path |
Limit the request paths that receive the cookie. A narrow path can prevent it being sent elsewhere on the same host. |
secure |
Use when the cookie is intended for secure transport, typically with an HTTPS target. |
httpOnly |
Mark that page JavaScript should not read the cookie with document.cookie. |
sameSite |
Specify the intended cross-site sending behavior using a documented value such as Lax. |
expires |
Set an expiry when the cookie should persist only until a particular time; otherwise session behavior may apply. |
partitionKey |
Supply partition information when the target cookie is partitioned. |
priority, sourceScheme |
Additional documented fields; the reference notes Chrome support for these fields. |
The references list name and value along with optional cookie metadata. Whether a site accepts or uses a particular combination depends on that site’s behavior and browser configuration; the API reference does not guarantee acceptance by every site. Verify field names and supported values against the version installed in your project: CookieData · CookieParam.
6. Use the default context or an isolated context
| Situation | Recommended API | Reason |
|---|---|---|
| Page is in the default context | browser.cookies(), browser.setCookie(), browser deletion methods |
Browser-level methods operate on the default context. |
| Page is in a separately created context | context.cookies(), context.setCookie(), context deletion methods |
Operate on the storage used by that page. |
| Remove a known cookie | deleteCookie() |
Use when you can identify the cookie directly. |
| Remove cookies matching criteria | deleteMatchingCookies() |
Use a filter for context-scoped cleanup. |
Creating a context does not make cookies set on another context appear there. Similarly, setting a cookie after navigation cannot change the request that already loaded the page; navigate or reload after setting it if the page must receive it on a request.
7. Troubleshoot common cookie problems
| Symptom | Likely cause | Fix |
|---|---|---|
| Cookie is missing from the request | The cookie was set on a different context, or its domain or path does not match the request. | Set it through the page’s owning context and align its URL/domain/path with the target request. |
| Cookie is absent on the first page load | It was set only after navigation. | Set it before page.goto(), then navigate. |
document.cookie does not show it |
The cookie may be httpOnly. |
Read it through context.cookies() or the default-context browser API. |
| Cookie set call rejects or cookie is not accepted | Attributes may be incomplete or inconsistent with the target site and URL. | Check the installed version’s cookie parameter types and verify intended URL, secure mode, domain, path, SameSite, and partition key. |
| Deletion call is obsolete or unavailable | Code uses the old Page-level deletion API or a different Puppeteer version. | Use the browser or owning BrowserContext deletion API documented for your installed version. |
| Cookie disappears between runs | The browser/context lifecycle or cookie expiry ends its lifetime. | Set it for each new context, or configure an appropriate expiry if persistence is intended. |
8. Performance, reliability, and cost
Cookie operations are usually a small part of an automation flow; navigation and page readiness commonly determine how long the overall job waits. Avoid creating needless contexts when their isolation is not needed, but use separate contexts when independent cookie state matters. Always close pages, contexts, and the browser in cleanup paths so a failed navigation does not leave browser processes running. Do not log real session values in production output, and keep authentication cookies in secrets storage rather than source control.
For repeatable runs, set cookies before navigation, make scope explicit, and keep the installed Puppeteer version and its type definitions aligned. Use a bounded navigation strategy suited to the page rather than waiting indefinitely; handle navigation timeouts as failures and decide whether retrying is safe for the task. Cookie APIs do not remove the cost of running and maintaining a browser: your compute, browser startup, concurrency, and storage setup determine operational cost.
9. Or skip the browser setup
If the job is to capture a page image or PDF rather than automate its session behavior, ScreenshotNeo provides a website screenshot API and MCP server. A single request captures the target URL; its cookie cleanup handles consent banners and removes known consent platforms, newsletter popups, and chat widgets before the shot. It is not a replacement for setting an authenticated Puppeteer session cookie when a site requires one.
cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);
See the ScreenshotNeo API documentation for options and response details. Bot checks, blank pages, timeouts, and failed loads are not billed; response headers identify the page verdict and billing status. ScreenshotNeo also provides an MCP server for AI agents to take screenshots. Plans include 1,000 screenshots per month free with no card, with paid plans starting at $5 for 3,000. Sign up free and get 1,000 screenshots a month with no card.
10. Frequently asked questions
Can I use cookies to log in to a site?
Only if the site accepts the cookie and its attributes and session state are valid. Authentication flows may also require other tokens or server-side state.
Can a popup use the cookies I set?
Pages opened within the same browser context share that context’s storage, including popups.
Should I use url or domain?
Use the parameter form supported by your installed Puppeteer version and make the intended host and path clear. The documented CookieParam.url can inform default domain, path, and source scheme.
Which Puppeteer version does this match?
The cited references include CookieData and BrowserContext at 25.12.0 and CookieParam at 25.11.0. Check the documentation and types shipped with your own installed version because API signatures can vary.


