SameSite defaults are changing: what you need to update

Chrome, Firefox, Edge, and other browsers are aligning with the IETF proposal Incrementally Better Cookies, which changes how cookies without a SameSite attribute behave:

  • Cookies without a SameSite attribute are treated as SameSite=Lax, restricting them to first-party contexts only.
  • Cookies intended for cross-site usage must explicitly specify SameSite=None; Secure to be included in third-party contexts.

If any of your cookies need to work in cross-site scenarios, you should update their attributes now to avoid them being blocked.

Which cookies actually need cross-site access?

Several common patterns depend on cookies being sent in third-party contexts. If you provide or rely on any of these, verify that the relevant cookies are marked correctly.

Content inside <iframe>s

Content from a different origin rendered in an <iframe> is in a third-party context. This includes:

  • Embedded media from other sites, such as videos, maps, code samples, and social posts.
  • External service widgets for payments, calendars, bookings, and reservations.
  • Less obvious <iframe>s used by social buttons or anti-fraud services.

Cookies here often maintain session state, store preferences, enable analytics, or personalize content for logged-in users. Because the web is composable, if you build embeddable content that relies on cookies, those cookies need explicit cross-site markers.

Cross-site "unsafe" requests

The term "unsafe" refers to requests that may change state, primarily POST. SameSite=Lax cookies are sent on safe top-level navigations such as link clicks, but a POST form submission to another site will not include cookies.

A common pattern is redirecting users to a third-party identity provider. Before the user leaves, your site sets a single-use token cookie expected on the return request to mitigate Cross-Site Request Forgery (CSRF). If that return request is a POST, the cookie must be marked SameSite=None; Secure.

Remote resources and API calls

Remote resources—such as <img> and <script> tags—may depend on cookies being sent with requests. Tracking pixels and content personalization are typical use cases.

The same applies to JavaScript requests via fetch with credentials: 'include' or XMLHttpRequest with withCredentials set to true. Any cookies included in those cross-site requests must be appropriately marked.

WebView content

A WebView in a native app is browser-powered, so the same restrictions apply. Android apps can also set cookies directly via the CookieManager API. If those cookies are intended for cross-site use, include SameSite=None; Secure when setting them.

Setting SameSite attributes now

For cookies used only in first-party contexts, set SameSite=Lax or SameSite=Strict depending on your needs. Relying on default browser behavior for unmarked cookies can produce inconsistent results across browsers and trigger console warnings.

js Set-Cookie: modern=1; SameSite=Lax

For cookies needed in third-party contexts, both attributes are required: SameSite=None without Secure will cause the cookie to be rejected.

js Set-Cookie: modern=1; SameSite=None; Secure

Handling browsers that don't support SameSite=None

Support for SameSite=None is still inconsistent across browsers. Refer to the compatibility list on chromium.org for known issues, though it may not be exhaustive.

One workaround is to set each cookie twice, in both new and legacy style:

js Set-Cookie: 3pcookie=value; SameSite=None; Secure Set-Cookie: 3pcookie-legacy=value; Secure

Browsers with new behavior use the cookie with the SameSite attribute. Older browsers ignore it and use the legacy version. When reading cookies, check for the new-style cookie first, then fall back to the legacy one. Here's an example in Node.js with Express and cookie-parser:

js const express = require('express'); const cp = require('cookie-parser'); const app = express(); app.use(cp()); app.get('/route', (req, res) => { // Get the cookie value, preferring the modern cookie const cookieVal = req.cookies['3pcookie'] || req.cookies['3pcookie-legacy']; // ... });

This requires setting redundant cookies and extra work at read time, but it keeps third-party cookies functional across all browser versions.

Alternatively, you can detect incompatible clients via the user-agent string when sending the Set-Cookie header. Refer to the list of incompatible clients and use a detection library such as ua-parser-js on Node.js. This requires only one change, but user-agent sniffing may miss some affected users.

Framework and language support

Most languages and frameworks support the SameSite attribute. However, SameSite=None is relatively new, so you may need to work around standard behavior. Known issues and examples are documented in the samesite-examples repository on GitHub.

Where to get help

Cookie usage spans the entire web, and no team knows every cross-site dependency in their codebase. If you hit an unusual issue, it may be a new one:

  • File an issue in the samesite-examples GitHub repository.
  • Ask on StackOverflow with the samesite tag.
  • For Chromium-specific problems, file a bug in the Chromium issue tracker.
  • Track Chrome's rollout via the SameSite updates page.