How it works
The snippet uses a four-state consent machine:
On each page load the snippet:
- Checks Global Privacy Control (GPC) immediately. If set, state is
deniedpermanently. - Looks for a loaded CMP (TCF v2.2, OneTrust, Cookiebot).
- Waits up to 300 ms for any CMP that loads via a tag manager after the snippet.
- If no CMP resolves: falls back to
no_cmp(cookies written, DNT still honoured).
EU sites without a supported CMP: if you serve EU/EEA visitors and use a custom cookie banner,
you must use the manual integration below. Otherwise the snippet enters
no_cmp mode and writes cookies before consent is obtained, which is an ePrivacy violation.Supported CMPs
IAB TCF v2.2
Detected automatically viawindow.__tcfapi. The snippet waits for the consent string to be ready and checks IAB Purpose 1 (Store and/or access information on a device).
If gdprApplies === false (visitor is outside GDPR jurisdiction), the snippet falls back to no_cmp.
No configuration required.
OneTrust
Detected viawindow.OnetrustActiveGroups. Analytics consent maps to group C0002 (Analytics Cookies).
No configuration required.
Cookiebot
Detected viawindow.Cookiebot.consent.statistics. Consent is granted when statistics === true.
No configuration required.
Global Privacy Control (GPC)
Detected vianavigator.globalPrivacyControl. If true, the snippet immediately enters denied and no events are ever fired for that visitor. Required under CPRA (California).
No configuration required.
Consent flip
If a visitor initially denies but later clicks “Accept All”, the snippet detects the change via the CMP callback and:- Writes
_traceten_sidand_traceten_vidcookies. - Fires a single
session_startevent with the anonymous session ID from before consent, so the backend can join pre-consent traffic to the now-identified visitor.
Manual integration
If you use a custom cookie banner (not OneTrust, Cookiebot, or a TCF-compliant CMP), you need two separate pieces of integration. They control different things, so do both.1. Gate tracking until consent (required for EU/EEA visitors)
SetconsentDefault: "pending" on the pre-load stub, before the snippet script tag. This tells the snippet to skip CMP auto-detection and the 300 ms no_cmp fallback entirely, and hold all tracking (no cookies, no events) until your banner explicitly resolves it:
data-site is your site key and data-cookie-domain is your own domain, so do not paste example.com: a value the page does not belong to is ignored and cookies quietly stay host-only.
Then, inside your banner’s own Accept/Reject handlers, call the snippet’s public resolveConsent():
resolveConsent("denied") writes a 30-day first-party opt-out cookie (exempt under ePrivacy Recital 66 as a user-initiated preference) so the visitor isn’t re-prompted every page load, and drops any queued events. resolveConsent("granted") starts tracking and, if the visitor had previously denied, fires a single session_start so pre-consent and post-consent traffic can be joined.
Without this step, a custom banner with no consentDefault set gets no gating at all: the snippet finds no CMP, waits 300 ms, and falls back to no_cmp (tracking on) regardless of what your visitor chose in your banner.
2. Unlock fingerprint signals (optional, additive)
Separately from the gate above, you can opt a visitor into two additional detection signals (canvas entropy, WebGL) once they’ve explicitly granted consent:Privacy guarantees
- No persistent cookies (
_traceten_sid,_traceten_vid,_traceten_cart) are written while state ispendingordenied. - GPC is always honoured, regardless of CMP configuration, and it cannot be overridden.
- All consent detection is read-only: the snippet never modifies your CMP state.
- Canvas entropy and WebGL signals are never collected in
pendingordeniedstates.
Testing your integration
- Open your browser’s Network tab and filter by
ingest.traceten.com. - Consent denied: no requests should appear.
- Consent granted: a
pageviewevent should appear within a few hundred milliseconds. - Consent flip (denied → granted): a
session_startevent should appear, followed by apageview.

