Untitled
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.
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)
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.