Cross-subdomain tracking
Many real sites span multiple hosts. The marketing pages live on www.example.com. The product app is app.example.com. Checkout is checkout.example.com. A user clicks an ad, lands on www, browses, signs up on app, pays on checkout. The click identifier needs to be readable from all three.
Trackbridge handles this with one config field — cookieDomain — and a handful of things to be aware of.
The basic setup
Section titled “The basic setup”Set cookieDomain to a parent domain shared by all the hosts you need:
import { createBrowserTracker } from '@trackbridge/browser';
export const tracker = createBrowserTracker({ adsConversionId: process.env.NEXT_PUBLIC_GOOGLE_ADS_CONVERSION_ID!, ga4MeasurementId: process.env.NEXT_PUBLIC_GA4_MEASUREMENT_ID!, consentMode: 'v2', cookieDomain: '.example.com', // ← the change});The leading . is conventional but not strictly required by browsers — both .example.com and example.com produce the same effect (a host-prefix-matching cookie). Pick one and use it consistently.
The cookies the SDK writes now include Domain=.example.com:
_tb_gclid=Cj0KCQ...; Domain=.example.com; Secure; SameSite=Lax; Path=/; Expires=<+90d>Browsers send these cookies on requests to www.example.com, app.example.com, checkout.example.com, and any other subdomain.
Apply the same setting on every subdomain
Section titled “Apply the same setting on every subdomain”The same cookieDomain must be passed to every createBrowserTracker instance across all your apps. If www writes Domain=.example.com and app writes Domain=app.example.com (because someone forgot the config), you end up with two separate cookies — app won’t read what www wrote.
The simplest discipline: make cookieDomain an environment variable (PUBLIC_TRACKBRIDGE_COOKIE_DOMAIN=.example.com), set it in every deployment, and pass it through. One source of truth across all your front-ends.
SPA navigations and shared sessions
Section titled “SPA navigations and shared sessions”If www and app are deployed as a single SPA (a Next.js app handling both / and /app/..., for example), this is mostly a non-issue — the cookie is set once and the same browser context reads it on every navigation. cookieDomain is only needed when the user crosses a real host boundary (full-page navigation to a different subdomain).
For full cross-host navigations:
- The browser sends the existing cookie automatically with the request to the new host.
- The new host’s
createBrowserTrackerreads the cookie at init viadocument.cookie. tracker.getClickIdentifiers()returns the captured value.
No extra forwarding code needed.
Reverse proxy / single host setups
Section titled “Reverse proxy / single host setups”If your “subdomains” are actually paths on a reverse-proxy fronted by one host (example.com/marketing/, example.com/app/, example.com/checkout/), cookieDomain doesn’t help — and isn’t needed. A normal host-only cookie works because the host doesn’t change. Skip the config entirely.
Cookie attributes that don’t change
Section titled “Cookie attributes that don’t change”Setting cookieDomain only adds the Domain= attribute. The other attributes are unchanged:
Secure— still required, still always set. HTTPS only.SameSite=Lax— sent on top-level navigations between subdomains, not on cross-site iframe loads.Path=/— available across the whole host.Expires— still 90 days by default.
What about apex vs subdomain
Section titled “What about apex vs subdomain”If your apex domain (example.com) also serves user traffic, it’s covered by Domain=.example.com (the leading-dot form makes the cookie available on the apex and any subdomain).
If Domain=example.com (no leading dot) is set, modern browsers behave the same way — the differentiation between Domain=.example.com and Domain=example.com was deprecated.
What you cannot do
Section titled “What you cannot do”- You cannot share cookies across two completely different domains (
example.comandanother-site.com). Browsers refuse on principle. If you need cross-domain attribution, that’s a different problem (Google’s “linker” parameter is the standard answer; Trackbridge does not implement it). - You cannot set
Domain=to a public suffix (Domain=.com,Domain=.co.uk). Browsers reject those values. Use your registrable domain. - You cannot read the cookie from a host outside the configured domain. A cookie with
Domain=.example.comis invisible tounrelated.com.
Verification
Section titled “Verification”Same recipe as the consent test, but across hosts:
- Open
https://www.example.com/?gclid=test123in a fresh incognito window. - Grant consent (if your tracker uses Consent Mode v2).
- DevTools → Application → Cookies. Confirm
_tb_gclid=test123exists withDomain=.example.com. - Navigate to
https://app.example.com/. - Open the console and run
document.cookie. Confirm_tb_gclid=test123is in the output. - Confirm
tracker.getClickIdentifiers()returns{ gclid: 'test123' }on the new host.
If step 5 fails, the Domain= attribute is wrong (or not set) on the original cookie.
See also
Section titled “See also”- Cookies — full attribute table.
- Click identifiers (gclid / gbraid / wbraid) — what’s actually being shared.