Puppeteer Cookie SameSite Values Explained
Learn what Puppeteer's Strict, Lax, and None cookie values do, how to set them, and how to debug cross-site cookie behavior in Chromium.
sameSite is an optional Puppeteer cookie property with three values: Strict, Lax, and None. Chromium decides when a cookie is sent: Strict limits it to same-site requests; Lax also permits cross-site top-level navigation with a safe method; and None permits cross-site use when paired with Secure. If you omit the attribute, Chromium documents a default of Lax. Puppeteer’s CookieData reference documents the fields, while Chromium’s SameSite guidance describes browser behavior.
What the three SameSite values mean
| Value | When Chromium may send the cookie | Typical fit |
|---|---|---|
Strict |
Same-site requests only. | Keep the cookie within same-site request flows, without carrying it into a cross-site entry. |
Lax |
Same-site requests and cross-site top-level navigation using a safe HTTP method. | First-party flows that should still work when a visitor follows a link to your site. |
None |
Same-site and cross-site requests, subject to browser requirements. | Flows that require third-party or other cross-site cookie use. Set Secure too. |
These are browser cookie policies, not special Puppeteer modes. Puppeteer lets you provide the cookie attributes; Chromium applies its rules when requests are made. For cookies used only in a first-party context, Chromium advises Lax or Strict. For third-party context, use SameSite=None; Secure.
Set SameSite in Puppeteer
Use the browser or browser context cookie API. Puppeteer marks the page-level Page.setCookie() API obsolete and points to Browser.setCookie() or BrowserContext.setCookie(). The following example uses a browser context and navigates to a local test page on the cookie’s origin.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({ headless: true });
try {
const context = await browser.createBrowserContext();
await context.setCookie({
name: 'session',
value: 'example-session-value',
url: 'https://example.com/',
sameSite: 'Lax',
httpOnly: true,
secure: true,
});
const page = await context.newPage();
await page.goto('https://example.com/', { waitUntil: 'domcontentloaded' });
console.log(await context.cookies('https://example.com/'));
} finally {
await browser.close();
}
Save this as an ES module such as cookie.mjs, install Puppeteer in your project, and run it with Node.js. Replace the example origin and cookie values with a site and test account you control. The sample sets secure: true because it targets HTTPS; for local HTTP development, account for the browser’s secure-cookie policy rather than assuming a production cookie will behave the same way.
Choose the value for the request flow
- Use
Strictif the cookie should accompany same-site requests only. - Use
Laxif same-site requests and safe cross-site top-level navigation should carry it. - Use
Noneonly when cross-site requests need the cookie, and setsecure: truefor theNone; Securerequirement. - Test the actual flow, browser, and request method. A cross-site form POST is not equivalent to following a link in a top-level navigation.
Cookie fields and scope
Puppeteer’s CookieData describes sameSite and secure as optional properties. A cookie also needs the right identity and scope: its name and value, and a URL or domain/path that matches the requests you want to inspect. A correct SameSite value cannot make a cookie for one host or path apply to another.
sameSite:'Strict','Lax', or'None'. If omitted, Chromium documents Lax as the default behavior.secure: whether the cookie is restricted to secure connections. Set it totruewithsameSite: 'None'.urlor domain/path: scope the cookie to the origin and paths used in the flow; use the field requirements in the Puppeteer API reference.httpOnly: useful for cookies that should not be exposed to page JavaScript; it does not change SameSite request rules.
Prefer an explicit SameSite value in automation when the test depends on a particular policy. This makes the intended behavior clear and avoids relying on a browser default. Do not treat an explicit attribute as a guarantee that a particular request will carry the cookie: scope, secure transport, navigation type, method, and browser policy still matter.
Debug cookies that are missing from a request
- Check the stored cookie. In DevTools, open Application storage and inspect its domain, path, SameSite, and Secure attributes. Confirm Puppeteer created the cookie for the expected origin.
- Inspect the actual request. In the Network panel, select the request and inspect whether the cookie was sent. Check the Console for browser warnings about blocked cookies.
- Reproduce the real context. Determine whether the request is same-site, a cross-site top-level navigation, an embedded/cross-site request, or a cross-site POST. Lax does not allow all of these contexts.
- Check timing and browser version. Run the flow in the target Chromium/browser build. Do not rely on historical temporary Lax+POST behavior as a compatibility guarantee.
Common errors and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Cookie appears in storage but is absent on a cross-site request. | Lax or Strict does not allow that request context. |
If the flow truly needs cross-site use, try sameSite: 'None' with secure: true, then inspect the request again. |
A None cookie is rejected or blocked. |
The cookie is missing Secure, or it is being tested over a connection that does not meet the browser’s secure-cookie requirements. |
Set secure: true and test the intended HTTPS deployment. |
| Cookie is not visible for the target host or route. | The URL/domain/path scope does not match. | Set the cookie against the intended origin and inspect its stored domain and path. |
| Link navigation works, but a cross-site POST fails. | Lax permits qualifying safe top-level navigation; a POST is a different method and context. |
Test the real POST flow. If cross-site cookie delivery is required, use None; Secure where browser policy permits. |
| Automation behaves differently from an older test run. | Browser policy or version differs, or the previous test depended on a temporary exception. | Record the browser version and test the complete flow directly rather than depending on a rollout flag or historical exception. |
Performance, reliability, and cost
Setting a cookie is generally a small part of an automation run; navigation, page scripts, and external services usually determine the overall wait. Choose a navigation readiness condition appropriate to the page, and avoid adding arbitrary delays as a substitute for checking the real request. For reliable results, isolate test contexts, use a controlled account and origin, and verify both the stored cookie and the outgoing request.
Cookie behavior is browser policy, so results can vary with browser version, transport security, and the exact flow. Keep a small regression case for the request type that matters to your application, especially cross-site POST or embedded requests. Puppeteer and Chromium themselves do not set a per-cookie price; infrastructure and browser execution costs depend on how you run the automation.
Or skip the browser setup
If your goal is to inspect a page rather than exercise its cookie flow, ScreenshotNeo can return a screenshot with one GET request. Its capture accepts cookie banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. ScreenshotNeo also has an MCP server with take_screenshot, get_page_info, and capture_pdf tools for AI agents.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for 1,000 free screenshots a month, with no card required.
FAQ
What happens when I leave SameSite out?
Chromium documents an omitted SameSite attribute as defaulting to Lax. Set it explicitly when a test requires a known policy.
Does SameSite=None alone enable third-party cookies?
No. Chromium’s guidance requires Secure alongside None, and the actual request still has to satisfy browser policy and cookie scope.
Should new Puppeteer code use page.setCookie()?
No. Puppeteer marks that page-level API obsolete and directs users to the browser or browser-context cookie APIs.
How can I tell whether a cookie is affected?
Inspect its stored attributes, check the actual request in DevTools, and reproduce the same navigation or request method that fails in your application.


