Sharing cookies between a headless Shopify storefront and its checkout
Tweek-Eek runs as a headless Shopify store: a Next.js storefront on tweek-eek.com, with the regular Shopify checkout on checkout.tweek-eek.com. Two applications on two hosts, and a visitor who should experience them as one shop.
Cookies do not cross that boundary by themselves. When I built the store I could not find a clear write-up on how to share cookies between the two domains — and how to update them safely — so this is the solution I ended up with.
Cookies are host-only by default
Set a cookie the obvious way on the storefront:
document.cookie = 'cookie_consent=true; Path=/'and it belongs to tweek-eek.com alone. The browser treats the checkout subdomain as a different host and never sends the cookie there. The visitor accepts cookies on the storefront, clicks through to pay, and the checkout has no idea a choice was ever made. Analytics break the same way: the session is cut in half at the exact step you care about most.
Sharing: scope the cookie to the registrable domain
The Domain attribute fixes the sharing part. A cookie set with Domain=.tweek-eek.com is sent to the apex domain and every subdomain under it, including the checkout:
document.cookie = [
'cookie_consent=true',
'Domain=.tweek-eek.com',
'Path=/',
'Max-Age=31536000',
'Secure',
'SameSite=None',
].join('; ')Or with a helper like cookies-next:
import { setCookie } from 'cookies-next'
setCookie('cookie_consent', 'true', {
domain: '.tweek-eek.com',
path: '/',
maxAge: 60 * 60 * 24 * 365,
secure: true,
sameSite: 'none',
})Three details that matter:
SameSite=NonerequiresSecure. The storefront and the checkout technically count as the same site, soLaxsurvives the redirect to checkout too, butNoneremoves any doubt for requests between the two hosts.- The leading dot is optional in modern browsers —
Domain=tweek-eek.combehaves identically — but it makes the intent readable. - A page can only widen a cookie to a domain its own host belongs to. Both hosts belong to
.tweek-eek.com, so both sides can read and rewrite the same cookie.
Updating: a cookie is identified by name, domain and path
This is the part I could not find documented anywhere. Writing a cookie with the same name but a different Domain does not update the original — it creates a second cookie. If you started host-only and later switch to Domain=.tweek-eek.com, visitors end up with two cookie_consent cookies, and which one a page reads is effectively undefined.
So always write a shared cookie with exactly the same domain and path, and if an old host-only version can exist, delete it explicitly before writing the new one:
document.cookie = 'cookie_consent=; Path=/; Max-Age=0'
setCookie('cookie_consent', 'false', {
domain: '.tweek-eek.com',
path: '/',
maxAge: 60 * 60 * 24 * 365,
secure: true,
sameSite: 'none',
})Shopify's cookies: don't forge them, request them
Sharing your own cookies is half the story. The checkout does not read cookie_consent — Shopify keeps consent in its own _tracking_consent cookie, a versioned, URL-encoded blob you should not construct by hand. Instead, ask the Storefront API to mint a valid value with the consentManagement query, aimed at the checkout domain:
const query = `query {
consentManagement {
cookies(
visitorConsent: { marketing: true, analytics: true, preferences: true }
origReferrer: ""
landingPage: "/"
) {
trackingConsentCookie
cookieDomain
}
}
}`
const res = await fetch('https://checkout.tweek-eek.com/api/unstable/graphql.json', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': storefrontToken,
},
body: JSON.stringify({ query }),
})
const json = await res.json()
const consent = json?.data?.consentManagement?.cookies?.trackingConsentCookieThe token here is the public Storefront API token, so it is safe in the browser. The response contains the exact cookie value Shopify expects — cookieDomain even confirms where it should live. Write it to the shared domain and the checkout picks it up as if it had set it itself:
if (consent) {
setCookie('_tracking_consent', decodeURIComponent(consent), {
domain: '.tweek-eek.com',
path: '/',
maxAge: 60 * 60 * 24 * 365,
secure: true,
sameSite: 'none',
})
}When the visitor changes their preferences later, run the same query with the new visitorConsent values and overwrite the cookie — same name, same domain, same path. Tracking on the checkout now follows the choice made on the storefront.
Verifying
Open DevTools → Application → Cookies on the storefront: the shared cookies should list .tweek-eek.com in the Domain column. Click through to the checkout and look again — same cookie, same value. Two rows with the same name but different domains means you have hit the update problem above: delete the host-only one.
None of this is exotic, but the pieces are scattered across cookie specs and half-related forum threads. Domain-scoped cookies for sharing, identical attributes for updating, and the Storefront API for anything Shopify itself needs to read.