Cookies and consent management (Web Experiment)
Consent gating runs Web Experiment without touching the visitor's device until they answer your cookie banner. While consent is undecided, the script still evaluates experiments and applies variants with no flicker, but it holds every cookie and browser storage write in memory, buffers impression events, and doesn't contact any third-party origin. When the visitor grants consent, the script flushes the held data to the device and sends the buffered impressions. When the visitor denies consent, the script discards the held data and erases anything it stored in earlier sessions.
Consent gating covers the Web Experiment script only. To gate Amplitude Analytics event collection on consent, use the Browser SDK's opt-out and deferred initialization instead. Refer to Cookies and consent management (Browser SDK).Enable consent gating
Set consentOptions on the window.experimentConfig object, above the Web Experiment script tag:
<script>
window.experimentConfig = {
consentOptions: {
consentRequired: true,
},
};
</script>
<!-- Web Experiment script tag -->
| Option | Default | Behavior |
|---|---|---|
consentRequired | false | When true, the script gates device storage and third-party requests on consent. When false, the consent feature is off and the script behaves as if it doesn't exist. |
consentStatus | 'pending' | The initial consent status, for visitors whose decision you already know when the page renders. One of 'granted', 'pending', or 'denied'. |
The script supports three status values:
pending: The visitor hasn't decided. The script runs entirely in memory.granted: The visitor consented. The script runs normally.denied: The visitor refused. The script erases its stored data, and the client doesn't start on this page load.
pending is only meaningful as an initial status. If your consent platform already knows the visitor's decision when the page renders, set consentStatus to 'granted' or 'denied' in the config so the script starts in the right state.
Update consent status at runtime
When the visitor answers the banner, call setConsentStatus from your consent management platform's callback:
window.webExperiment?.setConsentStatus("granted"); // or 'denied'
The script exposes setConsentStatus on window.webExperiment as soon as it loads, before the client finishes initializing, so a consent callback that fires early still lands. Guard the call with optional chaining in case the callback runs before the script tag itself loads.
A runtime status always wins over the consentStatus config value. Runtime transitions to pending log a warning and have no effect.
What happens in each state
While consent is pending
The script evaluates experiments and applies variants immediately, so visitors get a flicker-free experience whether or not they've answered the banner. Everything that normally lands on the device stays in memory instead:
- Cookie and browser storage writes go to an in-memory buffer.
- Impression events buffer instead of sending.
- The script doesn't load the cross-subdomain behavioral targeting relay frame.
If the visitor leaves the page without deciding, the buffered data disappears with the page. Nothing persists.
When the visitor grants consent
A granted status resolves the gates in place, without a page reload:
- Buffered storage writes flush to the device.
- Buffered impression events send once.
- The behavioral targeting relay frame loads.
If the page loaded with consent denied, the client didn't start, so a later grant (for example, a visitor who reopens your preference center and opts in) starts it fresh on the same page.
When the visitor denies or revokes consent
Adenied status, whether set at load or as a mid-session revocation, erases everything the script has stored on the device: the keys listed in Data the script stores, deleted from this origin's storage and from every cookie scope the script writes to. The script permanently discards impression events buffered before the denial. If the visitor opts back in later on the same page, the discarded impressions don't send.After a mid-session revocation the current page keeps its applied variants, running in memory with device writes suppressed, until the next navigation.
Data the script stores on the device
With consent granted (or with consent gating off), the script persists the following keys. <slice> is the first 10 characters of your project API key.
| Purpose | Storage | Keys |
|---|---|---|
| Visitor identity | localStorage, cookie | EXP_<slice>, EXP_<slice>_identity |
| First-seen date, landing page | localStorage, sessionStorage | EXP_<slice>_DEFAULT_USER_PROVIDER |
| Behavioral targeting | localStorage, cookie | EXP_<slice>_rtbt_events, EXP_<slice>_rtbt_session |
| Marketing attribution | localStorage, cookie | EXP_MKTG_<slice>, AMP_MKTG_ORIGINAL_<slice> |
| Redirect impressions | sessionStorage, cookie | EXP_<slice>_REDIRECT |
| Variant and flag caches | sessionStorage | amp-exp-* |
| Exposure queue and dedupe | localStorage, sessionStorage | EXP_unsent_*, EXP_sent_* |
| Refusal marker | cookie | EXP_<slice>_erased (written on denial, survives erasure) |
Notes
- Consent gating works with the anti-flicker snippet. Variants apply during
pending, so pages don't flicker while the visitor decides. - Denying Web Experiment consent doesn't opt the visitor out of Amplitude Analytics. Manage analytics consent separately with the Browser SDK.
- Preview and test links work regardless of consent status.
Was this helpful?