Chrome, Firefox, Edge, and others are changing their default behavior in line with the IETF proposal, Incrementally Better Cookies so that:
- Cookies without a
SameSite
attribute are treated asSameSite=Lax
, meaning the default behavior is to restrict cookies to first party contexts only. - Cookies for cross-site usage must specify
SameSite=None; Secure
to enable inclusion in third party context.
If you haven't already done so, you should update the attributes for your third-party cookies so they won't be blocked in the future.
Use cases for cross-site or third-party cookies
There are a number of common use cases and patterns where cookies need to be sent in a third-party context. If you provide or depend on one of these use cases, make sure that either you or the provider are updating their cookies to keep the service functioning correctly.
Content within an <iframe>
Content from a different site displayed in an <iframe>
is in a third-party context. Standard use cases include:
- Embedded content shared from other sites, such as videos, maps, code samples, and social posts.
- Widgets from external services such as payments, calendars, booking, and reservation features.
- Widgets such as social buttons or anti-fraud services that create less obvious
<iframes>
.
Cookies may be used here to, among other things, maintain session state, store general preferences, enable statistics, or personalize content for users with existing accounts.

Because the web is inherently composable, <iframes>
are also used to embed content viewed in a top-level or first-party context. Any cookies the site displayed in the iframe uses are considered third-party cookies. If you're creating sites that you want other sites to embed, and need cookies to make them work, you also need to ensure those are marked for cross-site usage or that you can fall back gracefully without them.
"Unsafe" requests across sites
"Unsafe" might sound concerning here, but it refers to any request that might be intended to change state. On the web, that's primarily POST requests. Cookies marked as SameSite=Lax
are sent on safe top-level navigations, like clicking a link to go to a different site. However, something like a <form>
submission to a different site using POST doesn't include cookies.

This pattern is used for sites that can redirect the user out to a remote service to perform some operation before returning, for example, redirecting to a third-party identity provider. Before the user leaves the site, a cookie is set containing a single use token with the expectation that this token can be checked on the returning request to mitigate Cross Site Request Forgery (CSRF) attacks. If that returning request comes through POST, you'll need to mark the cookies as SameSite=None; Secure
.
Remote resources
Any remote resource on a page, such as from <img>
tags or <script>
tags, might rely on cookies being sent with a request. Common use cases include tracking pixels and personalizing content.
This also applies to requests sent from your JavaScript using fetch
or XMLHttpRequest
. If fetch()
is called with the credentials: 'include'
option, those requests are likely to include cookies. For XMLHttpRequest
, expected cookies are usually indicated by a withCredentials
value fo true
. Those cookies must be appropriately marked to be included in cross-site requests.
Content within a WebView
A WebView in a platform-specific app is powered by a browser. Developers need to test whether the restrictions or issues that affect their apps also apply to their app's WebViews.
Android also lets its platform-specific apps set cookies directly using the CookieManager API. As with cookies set using headers or JavaScript, consider including SameSite=None; Secure
if they're intended for cross-site use.
How to implement SameSite
today
Mark any cookies that are only needed in a first-party context as SameSite=Lax
or SameSite=Strict
depending on your needs. If you don't mark these cookies and instead rely on default browser behavior to handle them, they can behave inconsistently across browsers and potentially trigger console warnings for each cookie.
Set-Cookie: first_party_var=value; SameSite=Lax
Make sure to mark any cookies needed in a third-party context as SameSite=None; Secure
. Both attributes are required. If you just specify None
without Secure
, the cookie will be rejected. To account for differences in browser implementations, you might need to use some of the mitigating strategies described in Handle incompatible clients.
Set-Cookie: third_party_var=value; SameSite=None; Secure
Handle incompatible clients
Because these changes to include None
and update default behavior are still relatively new, different browsers handle them in different ways. You can refer to the updates page on chromium.org for a list of known issues, but this list might not be exhaustive.
One possible workaround is to set each cookie in both the new and the old style:
Set-cookie: 3pcookie=value; SameSite=None; Secure Set-cookie: 3pcookie-legacy=value; Secure
Browsers implementing the newer behavior set the cookie with the SameSite
value. Browsers that don't implement the new behavior ignore that value and set the 3pcookie-legacy
cookie. When processing included cookies, your site should first check for the presence of the new style of cookie and, then fall back to the legacy cookie if it can't find a new one.
The following example shows how to do this in Node.js, using the Express framework and its cookie-parser middleware:
const express = require('express'); const cp = require('cookie-parser'); const app = express(); app.use(cp()); app.get('/set', (req, res) => { // Set the new style cookie res.cookie('3pcookie', 'value', { sameSite: 'none', secure: true }); // And set the same value in the legacy cookie res.cookie('3pcookie-legacy', 'value', { secure: true }); res.end(); }); app.get('/', (req, res) => { let cookieVal = null; if (req.cookies['3pcookie']) { // check the new style cookie first cookieVal = req.cookies['3pcookie']; } else if (req.cookies['3pcookie-legacy']) { // otherwise fall back to the legacy cookie cookieVal = req.cookies['3pcookie-legacy']; } res.end(); }); app.listen(process.env.PORT);
This approach requires you to do extra work setting redundant cookies and making changes at the point of both setting and reading the cookie. However, it should cover all browsers regardless of their behavior, and keep third-party cookies functioning.
As an alternative, you can detect the client using the user agent string when a Set-Cookie
header is sent. Refer to the list of incompatible clients, and use an appropriate user agent detection library for your platform, for example, the ua-parser-js library on Node.js. This approach only requires you to make one change, but user agent sniffing might not catch all affected users.
Support for SameSite=None
in languages, libraries, and frameworks
The majority of languages and libraries support the SameSite
attribute for cookies. However, because the addition of SameSite=None
is still relatively recent, you might need to work around some standard behavior for now. These behaviors are documented in the SameSite
examples repository on GitHub.
Getting help
Cookies are used everywhere on the web, and it's rare for any development team to have complete knowledge of where their site sets and uses them, especially in cross-site use cases. When you encounter an issue, it might be the first time anyone has encountered it, so don't hesitate to reach out:
- Raise an issue in the
SameSite
examples repository on GitHub. - Ask a question in the "samesite" tag on StackOverflow.
- For issues with Chromium's behavior, raise a bug in the Chromium issue tracker.
- Follow Chrome's progress on the
SameSite
updates page.