Cookie Management
How c15t manages cookies through script, iframe, and network gating
Cookie management is the most commonly misunderstood part of consent. A critical distinction: c15t does not manage all cookies on your site. It controls what scripts, iframes, and network requests are allowed to load - and those third-party resources are what set most cookies.
Understanding this distinction is key to building a compliant consent flow: c15t gates the sources of cookies, not the cookies themselves.
What Actually Sets Cookies
There are four sources of cookies on a typical website:
1. c15t itself
c15t stores the user's consent state in a c15t cookie (and mirrors it to localStorage). This cookie records which categories the user consented to, when they consented, and their subject ID. This is a strictly necessary cookie - it exists so the site remembers the user's consent choice.
2. Third-party scripts
When you load a tracking script (Google Analytics, Meta Pixel, etc.), that script sets its own cookies. Google Analytics creates _ga and _gid cookies. Meta creates _fbp and _fbc. These cookies are set by the script's code running in the browser - c15t prevents them by not loading the script until the user consents.
3. Embedded iframes YouTube embeds, social media widgets, and other iframes can set cookies via their embedded content. c15t's iframe blocker replaces iframes with placeholders until consent is granted, preventing these cookies from being set.
4. Network requests
Server responses can include Set-Cookie headers. If your page makes requests to third-party APIs or CDNs, those responses may set cookies. c15t's network blocker can intercept fetch and XMLHttpRequest calls to prevent these requests from happening without consent.
Info
Don't list these cookies in your banner. The cookie names above (_ga, _gid, _fbp, _fbc) are implementation details — they matter for developers understanding how tracking works, but they should not be exposed to end users in your consent UI. Users don't know what _ga means, and listing it doesn't help them make an informed choice. Instead, use purpose-based consent categories like "measurement" or "marketing" that communicate why data is collected, not how it is stored.
Why Revoking Consent Requires a Page Reload
When a user revokes consent for a category (e.g., turns off "measurement" after previously granting it), c15t reloads the page by default. This is not a limitation - it's the only reliable approach.
Why you can't just delete third-party cookies from JavaScript:
httpOnlycookies - Many tracking cookies are set with thehttpOnlyflag, which prevents JavaScript from reading or deleting them. Only the server that set them can remove them.- Domain restrictions - Cookies set on
.google.comor.facebook.comcan only be deleted by those domains. Your JavaScript running onyourdomain.comhas no access. - Alternative storage - Some scripts also write to
localStorage,sessionStorage,IndexedDB, or even Web Workers. Cleaning up all possible storage locations is impractical. - In-memory state - A loaded script has already executed. Its event listeners, timers, and in-memory data persist until the page unloads. You can't "unrun" JavaScript.
The reliable solution: don't load the scripts in the first place. A page reload creates a fresh execution context. On the fresh page, c15t reads the updated consent state and simply never loads the scripts that lost consent. No script means no cookies, no tracking, no in-memory state.
When reload does NOT happen:
- When a user is declining consent for the first time (no prior consent existed, so no scripts were loaded to clean up)
- When
reloadOnConsentRevokedis set tofalse - When the user is only adding consent (no revocations)
Configure reload behavior in the provider:
Info
The reload and deferred sync are part of the broader initialization flow. See Initialization Flow for the full sequence.
Info
Setting reloadOnConsentRevoked: false means previously-loaded scripts will continue running after consent is revoked. Only disable this if you have a specific strategy for handling script cleanup.
The Revocation Flow
When a user revokes consent, the following sequence occurs:
- User revokes consent — e.g. turns off "measurement" in the consent dialog
- New consent saved — updated preferences are written to cookies and localStorage
- Pending sync stored — the API update is deferred to localStorage (
c15t:pending-consent-sync) - Page reloads — a fresh execution context ensures revoked scripts never load
- Fresh init — c15t reads updated consent; scripts without consent are never loaded
- Deferred API sync — the pending consent change is sent to the backend and cleared from localStorage
Key detail: The API sync happens after the reload, not before. This ensures the page reloads as fast as possible. The pending sync data is stored in localStorage under the key c15t:pending-consent-sync and is picked up by the fresh page's initialization.
Last modified on February 10, 2026