Consent modes, GPC and Google Consent Mode
This page walks a privacy owner and a front-end engineer through the consent controls of the browser collector: the mode saved for each domain, the declaration on the script tag, the four consent categories, the treatment of Global Privacy Control (GPC) and Do Not Track (DNT), and the Google Consent Mode v2 bridge. It describes mechanisms. It is not legal advice; you decide which mode fits your notices.
What it is
Availability: Evaluation access. Availability depends on your plan, role and the modules enabled for your organisation.
The core script runs on every page without consent. It issues the session token, runs the minimal security check and answers server challenges. The extensions script carries device recognition, analytics, session replay and behavioral signals, and each of those lanes needs its own consent category: analytics, replay, deviceId or behavioral.
A consent mode, saved per domain, decides how the categories get their values:
| Mode | Stored as | Behaviour |
|---|---|---|
| Not required | not_required | Nothing waits for a visitor decision. A category is blocked when your page sets it to denied; every other category runs as configured. |
| API | api | Every category starts denied. Your page grants categories with setConsent. Default for new domains. |
| Cookie | cookie:<name> or cookie:<name>=<value> | The collector reads your consent cookie. A match grants all four categories; a missing or non-matching cookie denies them all. |
Domains created before the api default keep the mode they have.
When the mode is not not_required, the collector also enforces the decision on its own side. The loader adds an nxc parameter that lists the granted categories to collector requests, and the collector discards what you have not granted.
Prerequisites
- Workspace admin access to Backoffice → Integrations & API → Script & Consent. Without that role the settings are read-only. Saving needs a step-up MFA confirmation.
- A consent banner or consent management platform (CMP) whose decision your page can read, for
apimode, or a cookie from your own domain that it writes, forcookiemode. - The core tag installed as described in Install and Browser Runtime.
- For GPC and DNT policy changes: workspace admin access to Backoffice → Web Analytics & Privacy → Consent & Privacy, and for session replay Capture Policies.
- A decision from your privacy owner on the mode and on the legal basis. See Legal basis register and receipts and Cookies, storage and consent categories for your site.
Steps
1. Choose the consent mode for the domain
- Open Backoffice → Integrations & API → Script & Consent.
- Pick the domain in the Domain card.
- Open the Consent & extensions tab.
- Set Consent mode to one of:
Not required — nothing waits for a visitor decisionAPI — my page calls setConsent() (default for new domains)Cookie — read my consent cookie
- For Cookie, fill Cookie name and, if needed, Required value (optional). The name takes 1 to 64 letters, digits,
.,-or_. The value takes 1 to 128 letters, digits or. _ : % + -. Leave the value empty to treat any non-empty cookie as consent. Otherwise the URI-decoded cookie value must contain your text, so a CMP string such asOptanonConsentcan be matched on one group withC0002:1. - Select Save script & consent settings and confirm the MFA prompt.
The tab also holds the switch Load the extensions script automatically once consent is granted (immediately in Not required mode). In Not required mode it loads the extensions for every visitor, including those who declined your own banner, and the Backoffice shows a warning when you turn it on in that mode.
gcm is a client-side declaration, not a saved mode. The Backoffice rejects it.
In cookie mode the loader reads the cookie when it starts and again on visibilitychange and focus, so a decision made in your banner applies when the visitor returns to the tab. The cookie must be readable by script; an HttpOnly cookie is invisible to the loader.
2. Declare the mode on the tag (optional)
The saved mode reaches the browser with the session token. Until then, a client without a declaration behaves as not_required. If your decision reaches the page by API, declare the mode so the client is strict from its initial line of code:
<script
src="https://collect.noxtica.com/collector/noxtica-collector-core.js"
data-site-key="pk_prod_your_site_key_here"
data-consent-mode="api"
data-auto-init
data-auto-check-once
async
></script>
The Snippets tab adds this attribute with the switch Add data-consent-mode=“api” to the core snippet. The shorthand data-consent-cookie="<name>" or data-consent-cookie="<name>=<value>" declares a cookie mode. An invalid declaration is ignored.
| Mode saved for the domain | Declaration on the tag | Mode the client uses |
|---|---|---|
api or cookie:… | any | The saved mode. A tag can neither relax it nor swap it. |
not_required, or unset | api or cookie:… | The declared mode, so the client is gated before the token arrives. The collector does not enforce it on the server. |
not_required, or unset | none, invalid or not_required | not_required. |
A declaration is a client-side measure. A domain that must be enforced on the server needs the mode saved in the Backoffice.
getConsent() and the noxtica:consent-changed event carry modeResolved. It is false until the saved mode arrived with the token, and true afterwards. Wait while it is false. A loader older than 3.8.1 does not send the field, so undefined means “keep using mode”.
3. Connect your banner to the four categories
| Category | A grant enables |
|---|---|
analytics | Real-user monitoring, console-log capture, the interaction tracker and the durable client buffer. |
replay | Session replay recording and upload. |
deviceId | Persistent device storage and the persistent device-recognition token. The full page fingerprint also waits for it. |
behavioral | Behavioral biometrics, pointer and touch tracks, geolocation, cookie contents, favicon, extension and WebRTC probes. |
A granted category still depends on the features enabled for your domain. Consent never switches on a feature your configuration leaves off. For the legal classification of each feature, see Install and Browser Runtime.
Call setConsent from your banner. Each value is the string 'granted' or 'denied'; omitted keys keep their value:
function applyChoices(choices) {
const state = (allowed) => (allowed ? 'granted' : 'denied');
window.noxticaClient.setConsent({
analytics: state(choices.statistics),
replay: state(choices.statistics),
deviceId: state(choices.preferences),
behavioral: state(choices.marketing),
});
}
// Run when your decision is known and the client exists.
document.addEventListener('noxtica:ready', () => applyChoices(readMyChoices()), { once: true });
Then load the extensions, unless Load the extensions script automatically once consent is granted or data-extensions="auto" does it for you:
const result = await window.noxticaClient.loadExtensions();
if (!result.ok) console.warn(result.reason, result.code);
Legacy forms keep working: setConsent('granted' | 'denied') sets analytics, and setReplayConsent(true | false) sets replay.
What a denial does:
deviceIddenied: the persistent device stores are deleted and the device id stays in memory andsessionStorage.analyticsdenied: the tracker and RUM stop and the buffered analytics events are purged.replayrevoked while recording: the recorder detaches.- A repeated call with the same values changes nothing and fires no
noxtica:consent-changed.
In Not required mode a grant is not needed: an explicit denied is the sole value that blocks a category. When persistent device recognition is switched off for the domain, a gated mode never writes the persistent device id, even after deviceId is granted.
A page check that your banner has not yet allowed is skipped, not failed. noxtica:collected then carries skipped: 'consent_required', and the check runs by itself when deviceId is granted later on the same page.
4. Decide how to treat GPC and DNT
The browser reports the signal in getConsent().privacySignal: 'gpc' when navigator.globalPrivacyControl is true, 'dnt' when navigator.doNotTrack is '1' or 'yes', otherwise null. The field is a local flag; the loader adds it to no request body. Browsers also send Sec-GPC or DNT request headers, and the collector reads those.
The domain policy decides what the signal does:
| DNT/GPC policy | A visitor who sends the signal |
|---|---|
Honor (default) | The tracker (clicks, scroll dwell, page views and custom events), console-log capture and RUM do not run for that visitor. |
Documented override | Those lanes run. Your tenant has recorded a legal basis that overrides the signal. |
Set the policy in Backoffice → Web Analytics & Privacy → Consent & Privacy. The page lists domains that still need a consent or privacy decision. For each one, set Legal basis, Requires consent and DNT/GPC policy. Documented override needs an approved legal basis and the checkbox Acknowledge documented override. Saving needs step-up MFA.
Session replay has its own DNT/GPC policy, with the same two values, in its replay policy under Backoffice → Web Analytics & Privacy → Capture Policies. See Session replay.
The collector backs the client up. With policy Honor and a request that carries Sec-GPC: 1 or DNT: 1:
POST /client/trackeranswers200with{ "ok": true, "eventsProcessed": 0, "reason": "dnt_gpc_honored" }, and nothing is stored.- Console-log upload is refused with
console_logs_dnt_gpc_honored. - For replay, the replay policy call answers
{ "ok": false, "enabled": false, "reason": "replay_dnt_gpc_honored" }and no upload capability is issued.
The loader does not read the signal in the core steps: the session token, the minimal security check, the anti-automation counters and protected actions.
5. Bridge Google Consent Mode v2 (optional)
Use the bridge when your CMP already drives Google Consent Mode. Turn it on in one of four ways:
<script
src="https://collect.noxtica.com/collector/noxtica-collector-core.js"
data-site-key="pk_prod_your_site_key_here"
data-consent-mode="gcm"
data-auto-init
async
></script>
noxtica('consent', 'gcm'); // command queue; also client.enableGoogleConsentMode() or createClient({ consentMode: 'gcm' })
What the bridge does:
- It reads Google’s consent state from
window.google_tag_data.ics, listens for changes toanalytics_storageandad_storage, and picks up a decision made before the collector loaded. If Google’s state is not on the page yet, nothing is granted, and the bridge checks once a second for about five minutes. analytics_storagemaps to theanalyticscategory and to nothing else.replay,deviceIdandbehavioralkeep needing your explicitsetConsent.ad_storageis read and ignored.- It can tighten and cannot loosen. On a domain saved as
apiorcookie, Google can deny what your decision allowed, and can never grant what the saved mode withholds. On a domain saved asnot_required, a tag that declaresgcmmakes the client behave as gated until Google saysgranted. getConsent().modereadsgcmwhile the bridge is on, and each real change fires onenoxtica:consent-changed.
Google Consent Mode is a signal format. It is not a legal basis, and mapping it to a single category keeps a Google analytics_storage grant from being read as consent to replay or device recognition.
6. Test the result
- Load the page in a clean profile with your banner unanswered. In DevTools → Network you see the core script and
POST /client/token.localStorageholds nonox_keys, andsessionStorageholds the token. - Read the effective mode after the token arrived:
document.addEventListener('noxtica:collected', () => {
const consent = window.noxticaClient.getConsent();
console.assert(consent.mode === 'api', 'unexpected consent mode', consent);
});
- Answer the banner with consent. Expect
noxtica:consent-changed, thennoxtica:extensions-loaded, then anoxtica:collectedwith afingerprintId. Collector requests now carrynxc=with one letter per granted category:aanalytics,rreplay,ddeviceId,bbehavioral. - Withdraw a category and confirm the matching storage disappears.
Once the extensions are loaded, the events noxtica:consent-rejected and noxtica:consent-reset on window purge the durable analytics buffer. Dispatch one from your banner when a visitor rejects or resets consent and you want that purge: window.dispatchEvent(new CustomEvent('noxtica:consent-rejected')).
Verify it works
getConsent()shows the mode you saved andmodeResolved: true.- Before consent in a gated mode, the page makes no call to Noxtica other than the core script and
POST /client/token, andnoxtica:collectedreportsskipped: 'consent_required'. - After consent, the extensions load,
nxcappears on collector requests andnoxtica:collectedcarries afingerprintId. - For a visitor with GPC on and policy
Honor,privacySignalis'gpc'and no tracker or RUM request leaves the page.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
getConsent().mode is not_required right after load on an api domain | The saved mode has not arrived. modeResolved is false. | Wait for noxtica:consent-changed, or declare data-consent-mode="api" on the tag. |
| The extensions load for visitors who declined your banner | The domain is in Not required mode, with Load the extensions script automatically once consent is granted on or a legacy script URL | Switch the domain to API or Cookie, or turn the switch off. |
setConsent does nothing in Not required mode | In that mode denied is the sole value with an effect | Use API or Cookie mode when visitors must decide first. |
TypeError: NoxticaCollector.setConsent requires granted, denied, or { analytics, replay, deviceId, behavioral } | You passed true, false or another shape | Pass the strings 'granted' or 'denied'. |
| Cookie mode never grants | The cookie name differs, the value is not contained in the decoded cookie, or the cookie is HttpOnly or set on another host | Match the name exactly and use a script-readable first-party cookie. |
| In cookie mode a banner change is seen late | The loader reads the cookie at start and on visibilitychange and focus | Reload, or switch tabs and return. |
noxtica:collected has skipped: 'consent_required' | deviceId is not granted in a gated mode | Grant deviceId after the visitor agrees. This is not an error. |
| Google bridge grants nothing | Google’s consent object is not on the page, or solely ad_storage changed | Make the Google consent default and update run on the page. The bridge reads analytics_storage. |
| The Backoffice says a setting is not available on the workspace’s database version yet | The setting is not enabled for your organisation | Nothing is written. Try again later or contact your account team. |
| Saving asks for MFA | Changing the consent mode is a step-up action | Complete the prompt. |
| The consent controls are read-only | Your role is not workspace admin | Ask a workspace admin. |
Related
- Install and Browser Runtime: install, storage disclosure and the legal classification table.
- Client API, events and the command queue:
setConsent,getConsentand the consent events. - Script attributes and client options:
data-consent-mode,data-consent-cookieanddata-extensions. - Protected actions: the minimal security check that runs without consent.
- Cookies, storage and consent categories for your site: what to disclose in your cookie notice.
- Legal basis register and receipts: recording the basis behind a DNT/GPC override.
- Cookie policy: Noxtica’s own cookie notice.