Integration recipes

CookieGuard exposes a small public JS API. These recipes show how to gate third-party scripts and pixels on consent — for stacks that load scripts dynamically (Nuxt 3, Next.js, Astro) and for vendors that have their own opt-in APIs.

Consent categories & the consent object
Every API surface below hands you the same object — one boolean per category. Gate each script on the category it belongs to.
{
  necessary:   true,   // always true — cannot be disabled
  preferences: false,  // functionality (e.g. language, theme)
  analytics:   false,  // GA4, Mixpanel, PostHog, …
  marketing:   false,  // ad + affiliate pixels, Meta Pixel, …
  sensitive:   false,  // health data — Healthcare plan only (MHMDA / NV SB 370)
  ts:          1736600000000 // epoch ms of the decision
}

Stored in a first-party cookie named cookieguard_consent. getConsent() returns null until the visitor makes a decision. For a new visitor, the non-necessary categories default to denied under GDPR-style regimes (opt-in) and granted under opt-out regimes — CookieGuard decides this from the visitor's region and your enabled regulations. sensitive is never pre-checked.

The public JS API
Use this from anywhere on the page. Handlers queued before the script loads are drained automatically.
// Safe to call before the cookieguard script has loaded:
window.cookieguard = window.cookieguard || { q: [], on(...a) { this.q.push(['on', a]) } }

// Fired once, when the banner state is settled (consent loaded or banner shown).
window.cookieguard.on('ready', (consent) => {
  // consent is null if no decision yet
})

// Fired on every change after consent is granted, customized, or reset.
window.cookieguard.on('change', (consent) => {
  if (consent?.categories.analytics) initAnalytics()
  if (consent?.categories.marketing) initMarketing()
  if (consent?.categories.sensitive) initHealthFeatures() // MHMDA / NV SB 370
})

// Read current consent any time:
const current = window.cookieguard.getConsent()

// Re-open the preferences modal from a "Manage cookies" link:
window.cookieguard.openPreferences()

// Remove a handler:
window.cookieguard.off('change', myHandler)

// Clear the stored decision, apply denied signals, and notify listeners:
window.cookieguard.reset({ reload: false })

// Revoke or grant vendor state when categories change:
window.cookieguard.registerIntegration('marketing', {
  grant: () => startVendor(),
  revoke: () => stopVendorAndClearItsState(),
})

// Privacy-safe runtime/configuration diagnostics:
console.log(window.cookieguard.diagnostics())

// Or use the DOM event (preferred by some frameworks):
document.addEventListener('cookieguard:consent', (e) => {
  console.log(e.detail) // normalized decision with a categories object
})
Nuxt 3 + @nuxt/scripts
Load GTM, GA4, and Meta Pixel as independent scripts gated on consent.
// plugins/cookieguard.client.ts
export default defineNuxtPlugin(() => {
  const w = window as any
  w.cookieguard = w.cookieguard || { q: [], on(...a: any[]) { this.q.push(['on', a]) } }

  const load = (consent: any) => {
    if (!consent) return

    if (consent?.categories.analytics) {
      useScript({
        src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXX',
        async: true,
      })
    }

    if (consent?.categories.marketing) {
      useScript({
        src: 'https://connect.facebook.net/en_US/fbevents.js',
        async: true,
      })
    }
  }

  w.cookieguard.on('ready',  load)
  w.cookieguard.on('change', load)
})
Google Tag Manager + Consent Mode v2
CookieGuard pushes default-denied and updated consent signals automatically when Google Consent Mode is enabled in your site settings.

Turn on Settings → Integration → Google Consent Mode on your site. We will push:

gtag('consent', 'default', {
  analytics_storage: 'denied',
  ad_storage: 'denied',
  ad_user_data: 'denied',
  ad_personalization: 'denied',
  functionality_storage: 'denied',
  personalization_storage: 'denied',
  security_storage: 'granted',
  wait_for_update: 500,
})

// After the visitor decides:
gtag('consent', 'update', {
  analytics_storage:        consent.categories.analytics  ? 'granted' : 'denied',
  ad_storage:               consent.categories.marketing  ? 'granted' : 'denied',
  ad_user_data:             consent.categories.marketing  ? 'granted' : 'denied',
  ad_personalization:       consent.categories.marketing  ? 'granted' : 'denied',
  functionality_storage:    consent.categories.preferences ? 'granted' : 'denied',
  personalization_storage:  consent.categories.preferences ? 'granted' : 'denied',
})

You still need to set GTM tags to honor these signals (Advanced → Consent Settings → Require additional consent).

Deny-before-interaction: Use the site-specific bootstrap shown in the Installation tab as the first script in<head>. It writes the denied default synchronously before loading the runtime; CookieGuard sends updates after decisions and on returning visits.

<!-- First in head, before GTM/gtag/GA4/Ads -->
<script src="https://cookieguard.co/api/v1/bootstrap/YOUR_SITE_ID?key=YOUR_PUBLISHABLE_SITE_KEY&language=auto"></script>
Tagged Script Blocking (data attributes)
Gate third-party scripts without writing any JS. Turn on Settings → Advanced → Tagged Script Blocking on your site, then mark each script.
<!-- Change type to "text/plain" and tag it with a category. -->
<script type="text/plain" data-cookieguard="analytics"
        src="https://www.googletagmanager.com/gtag/js?id=G-XXXX"></script>

<script type="text/plain" data-cookieguard="marketing">
  /* inline marketing snippet */
</script>

When the visitor grants that category, CookieGuard re-inserts the script as a live <script> so it executes. Use analytics, marketing, or preferences as the value. Necessary scripts should load normally. Re-blocking after a revocation takes effect on the next page load.

Meta Pixel
When loaded directly (not via GTM), gate fbq initialization on consent.
window.cookieguard.on('change', (consent) => {
  if (!consent?.categories.marketing) return
  // Standard Meta Pixel loader, only fired after consent:
  !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
  n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
  n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
  t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}
  (window, document,'script','https://connect.facebook.net/en_US/fbevents.js');
  fbq('init', 'YOUR_PIXEL_ID')
  fbq('track', 'PageView')

  // Healthcare plan: push Meta's Limited Data Use when health regulations
  // apply for this visitor (MHMDA / Nevada SB 370):
  if (!consent?.categories.sensitive && (isWashingtonVisitor || isNevadaVisitor)) {
    fbq('dataProcessingOptions', ['LDU'], 1, 1000)
  }
})
Mixpanel and PostHog
Both vendors have built-in opt-in/opt-out APIs. Use them rather than blocking the script — you get nicer behavior if a user revokes consent mid-session.
window.cookieguard.on('change', (consent) => {
  if (consent?.categories.analytics) {
    mixpanel.opt_in_tracking()
    posthog.opt_in_capturing()
  } else {
    mixpanel.opt_out_tracking()
    posthog.opt_out_capturing()
  }
})
Sentry
Error monitoring is generally classified as necessary (operational). Be careful if your breadcrumbs capture PII — in that case, gate it under analytics instead.
Sentry.init({
  dsn: 'https://…',
  // Default: keep on (necessary). Comment out the next line if you want
  // to gate Sentry under analytics consent instead:
  beforeSend(event) {
    const consent = window.cookieguard?.getConsent?.()
    if (!consent?.categories.analytics) return null
    return event
  },
})
Affiliate pixels (Everflow, FirstPromoter)
Gate these under marketing. Note that affiliate attribution will break for visitors who reject marketing — this is the correct compliance behavior, but worth flagging to your growth team.
window.cookieguard.on('change', (consent) => {
  if (!consent?.categories.marketing) return
  // Everflow
  EF.click({ offer_id: '…', affiliate_id: '…' })
  // FirstPromoter
  ;(function() {
    const s = document.createElement('script')
    s.src = 'https://cdn.firstpromoter.com/fpr.js'
    document.head.appendChild(s)
  })()
})