Skip to main content
Traceten uses no local storage, session storage, or IndexedDB. It uses only first-party cookies, and only once consent is resolved, and it integrates with your existing consent management platform (CMP). No configuration is required for supported CMPs: the snippet detects them automatically.

How it works

The snippet uses a four-state consent machine: On each page load the snippet:
  1. Checks Global Privacy Control (GPC) immediately. If set, state is denied permanently.
  2. Looks for a loaded CMP (TCF v2.2, OneTrust, Cookiebot).
  3. Waits up to 300 ms for any CMP that loads via a tag manager after the snippet.
  4. 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 via window.__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 via window.OnetrustActiveGroups. Analytics consent maps to group C0002 (Analytics Cookies). No configuration required.

Cookiebot

Detected via window.Cookiebot.consent.statistics. Consent is granted when statistics === true. No configuration required.

Global Privacy Control (GPC)

Detected via navigator.globalPrivacyControl. If true, the snippet immediately enters denied and no events are ever fired for that visitor. Required under CPRA (California). No configuration required. If a visitor initially denies but later clicks “Accept All”, the snippet detects the change via the CMP callback and:
  1. Writes _traceten_sid and _traceten_vid cookies.
  2. Fires a single session_start event 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. Set consentDefault: "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:
Both values come from your site’s install page. 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.
window.traceten.resolveConsent is only defined once the snippet script has finished loading. If your banner can be accepted before that (a fast click on a slow connection), queue the call yourself and replay it from the script tag’s onload handler. The pre-load stub above does not know how to queue resolveConsent the way it queues track().
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.
Denial must be re-asserted on every page load. The opt-out cookie that resolveConsent("denied") writes suppresses the persistent visitor cookie and the higher-entropy device signals, but it does not feed back into the consent state. On the next page load the state starts as pending and falls to no_cmp after 300 ms unless your banner calls resolveConsent("denied") again. If you are relying on consent state to honor a GDPR Article 21 objection, make sure your banner re-asserts the denial on every load, not just the one where the visitor clicked. See Opt-out and Do Not Track.

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:
window.traceten.consent = "granted" only unlocks the fingerprint signals above. It is not a substitute for resolveConsent() and does not gate event firing on its own. Skipping it does not break tracking; it means detection runs without those two signals for that visitor.
If your site spans multiple subdomains and you want this consent decision to carry across all of them, see Consent across subdomains. The same broadening has a real tradeoff, so it is documented there rather than repeated here.

Privacy guarantees

  • No persistent cookies (_traceten_sid, _traceten_vid, _traceten_cart) are written while state is pending or denied.
  • 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 pending or denied states.
For a full list of what data is collected, see Data collected.

Testing your integration

  1. Open your browser’s Network tab and filter by ingest.traceten.com.
  2. Consent denied: no requests should appear.
  3. Consent granted: a pageview event should appear within a few hundred milliseconds.
  4. Consent flip (denied → granted): a session_start event should appear, followed by a pageview.