Guide
Getting started
Two steps: mark the tags that need consent, then describe your categories.
npm install @devix-labs/cookie-consent
1. Block what needs consent
A blocked tag is inert markup — it is not fetched, it does not run, it sets nothing.
<!-- A script, blocked until "analytics" is allowed. -->
<script type="text/plain" data-cc="analytics" src="https://example.com/analytics.js"></script>
<!-- Inline code, the same way. -->
<script type="text/plain" data-cc="analytics">
window.dataLayer.push({ event: 'page_view' });
</script>
<!-- An embed: the src is held back in data-cc-src. -->
<iframe data-cc="marketing" data-cc-src="https://www.youtube.com/embed/xyz" title="A video"></iframe>
<!-- A tracking pixel. -->
<img data-cc="marketing" data-cc-src="https://example.com/pixel.gif" alt="">
data-cc takes:
| Value | Means |
|---|---|
analytics |
that category |
analytics marketing |
both categories must be allowed |
analytics/ga4 |
one service inside a category |
ga4 |
the same service, by its own id |
2. Describe the categories
import { createCookieConsent } from '@devix-labs/cookie-consent';
import '@devix-labs/cookie-consent/styles.css';
const consent = createCookieConsent({
policyUrl: '/privacy',
version: 1, // bump it when your policy changes, and everyone is asked again
categories: [
{ id: 'necessary', label: 'Strictly necessary', description: 'Keeps the site working.', required: true },
{
id: 'analytics',
label: 'Analytics',
description: 'Helps us see which pages are useful.',
autoClear: [{ name: '_ga' }, { name: '_ga_.*', pattern: true }],
services: [
{ id: 'ga4', label: 'Google Analytics 4', url: 'https://policies.google.com/privacy', cookies: [{ name: '_ga', duration: '2 years', description: 'Tells visits apart' }] },
],
},
{ id: 'marketing', label: 'Marketing' },
],
});
That is it. The notice appears, nothing non-essential runs until someone decides, and the decision is remembered for six months.
Google Consent Mode v2
Analytics and Ads do not run properly in Europe without it. The defaults have to be set before any
Google tag, so put this in the <head>:
<script type="module">
import { consentModeDefaults } from 'https://www.devix.pk/cdn/oss/cookie-consent@1.0.0/index.js';
consentModeDefaults(); // everything denied, wait_for_update: 500ms
</script>
Then switch it on in the config, and a decision sends the update automatically:
createCookieConsent({
consentMode: { map: { analytics_storage: 'analytics', ad_storage: 'marketing', ad_user_data: 'marketing', ad_personalization: 'marketing' } },
categories: [/* … */],
});
Where in the world
createCookieConsent({
regime: 'auto',
country: () => fetch('/api/where').then((r) => r.text()), // 'DE', 'AE', 'US-CA'…
categories: [/* … */],
});
| Regime | Where | Before a choice |
|---|---|---|
gdpr |
EU/EEA, UK, Switzerland | nothing non-essential runs |
pdpl |
UAE, Saudi Arabia, Qatar, Bahrain, Oman, Kuwait | nothing non-essential runs |
lgpd |
Brazil | nothing non-essential runs |
ccpa |
California and the other US opt-out states | preselected categories may run |
default |
everywhere else | nothing non-essential runs |
Global Privacy Control and Do Not Track are treated as a refusal everywhere, recorded as such, and the notice is never shown to that visitor.
Keeping the proof
createCookieConsent({
report: (record) => navigator.sendBeacon('/api/consent', JSON.stringify(record)),
noticeHash: 'sha256-…', // a hash of the exact wording you showed
categories: [/* … */],
});
The record is what a regulator asks for: who decided (an id you can match to your log), when, what they refused, which version of your policy, which regime and which language.
Our Laravel package stores these for you, with a migration and an endpoint:
composer require devix-labs/laravel-cookie-consent.
A settings link in your footer
<a href="#" data-cc-open>Cookie settings</a>
Any element with data-cc-open opens the preferences. No wiring.