Skip to content
Devix Open Source

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.

Updated 15 Sep 2026