Cookie Consent
Blocks scripts until consent, supports Consent Mode v2, GDPR and UAE PDPL.
npm install @devix-labs/cookie-consent
Scripts marked for consent stay inert markup until their category is allowed — never fetched, never run. Google Consent Mode v2 is denied by default and updated the moment someone decides, Global Privacy Control is treated as a refusal without anyone being asked, and every decision becomes a record with an id, timestamps, refusals, your policy version, the regime and a hash of the wording, ready to send to your own log. GDPR, UAE PDPL, LGPD and the US opt-out states are built in. 6.9 KB, no dependencies.
What you get
It actually blocks
A tag with data-cc is inert markup until its category is allowed: no request, no cookie, no run. Withdraw consent and an embed leaves the page there and then.
Google Consent Mode v2
Denied by default with wait_for_update and ads_data_redaction, then all seven signals updated to match the decision. Without it, Analytics and Ads do not run in Europe.
Global Privacy Control
A browser-level refusal is law in California, Colorado and Connecticut. Here it is honoured, recorded as the reason, and the notice is never shown.
Proof, not a flag
Every decision is a record: id, both timestamps, what was refused, the policy version, the regime, the language and a hash of the exact wording — handed to report() for your server.
Regimes
GDPR, UAE PDPL and the GCC, Brazil's LGPD and the US opt-out states decide whether anything may run before a choice. Add your own.
6.9 KB, no framework
klaro ships Preact at 52.6 KB to draw a banner. The most-installed free library has not been released since 2019 and blocks nothing at all.
Cookie Consent — overview
Why it exists
Most consent banners are decoration: the tags load anyway, and the banner records nothing. The most installed free library (Osano's) has not been released since 2019 and blocks nothing at all. The best maintained one has "become a Google-certified CMP" as its most-reacted open issue, which means Analytics and Ads do not run properly in Europe for anyone using it.
What it does differently
- Blocking is the product. Tags are inert markup until their category is allowed, and withdrawing consent pulls an embed back off the page.
- Google Consent Mode v2 built in, denied by default, with all seven signals mapped to your categories.
- Browser signals honoured. Global Privacy Control is law in several US states; here it is a refusal that is recorded without anyone being asked.
- A record, not a cookie flag. Id, timestamps, what was refused, the policy version, the regime,
the language and a hash of the wording — the proof a regulator asks for.
report()sends it to your server. - Regimes. GDPR, UAE PDPL, LGPD and the US opt-out states decide whether anything may run before a choice.
- 6.9 kB, no framework.
Shape of the package
| Entry | What |
|---|---|
@devix/cookie-consent |
createCookieConsent — the notice, the preferences dialog and the engine |
@devix/cookie-consent/core |
the state machine, blocking, Consent Mode and regimes, with no UI |
/react, /vue, /svelte, /element |
the same thing, wrapped |
/styles.css, /styles.layer.css |
the theme, plain or inside @layer devix |
Not in 1.0
A cookie scanner that crawls your site, and IAB TCF 2.2, are the Pro edition's shape. The Laravel package (proof-of-consent log) and the WordPress plugin are separate products in this catalogue.
Demos
All demos →It actually blocks
Three tags are on this page and none of them has run. Accept, and watch the counters move — and only the ones...
Categories, services, cookies
The preferences screen: per-service switches, dependencies, and the cookie table a data protection officer ask...
Google Consent Mode v2
Every signal denied before a choice, then updated to match it — the dataLayer entries, as Google receives them...
Layouts and languages
Box, bar or centre; light or dark; English, Arabic or Urdu — including the category labels, right to left.
How it compares
Questions
How is this different from the banner I already have?
Most banners are decoration: the tags load regardless. Here a consent-marked script has type="text/plain", so the browser treats it as data — it is never fetched and never runs until its category is allowed. Our own tests assert it by counting whether the blocked scripts executed.
Do I need Google Consent Mode?
If you use Analytics or Ads and have European visitors, yes — without it those tags do not run properly. Call consentModeDefaults() in the head before any Google tag, set consentMode in the config, and the update is sent for you.
Does it work with Tag Manager?
Both ways. Block the GTM script itself with data-cc, or — better with Consent Mode — let GTM load, deny everything by default, and let your decision release the tags inside the container.
What about a strict Content Security Policy?
Pass your nonce and it is copied onto every script we unblock. We never inject a style element, so style-src 'unsafe-inline' is not needed either.
Where is the decision stored, and can my server read it?
In a first-party cookie named dx_consent, as JSON, for 182 days by default — so your server can read it and render tags server-side. Switch to localStorage if you prefer, and set a domain to share one decision across subdomains.
Can I keep a log for the regulator?
Yes — that is what report() is for, and what our Laravel package stores: the record carries an id, timestamps, the refusals, the policy version, the regime, the language and a hash of the notice text, so the proof survives a redesign.
Can I translate it?
Everything, including service labels and cookie descriptions: any label takes { en: '…', ar: '…' } and follows the page language. RTL mirrors itself.
More from Devix
All resources →Toast
UI component
Promise-aware toasts with stacking, swipe to dismiss and correct live regions.
Confirm Dialog
UI component
Promise-based dialogs on native <dialog>: confirm, prompt and type-to-confirm.
Command Palette
UI component
A framework-free ⌘K palette with nested pages, async sources and shortcuts.