Skip to content
Get started

Google Consent Mode v2

<ConsentMode /> forwards the visitor’s choice to Google tags (GA4, Google Ads, Google Tag Manager) as Consent Mode v2 signals. It sets an all-denied default before any Google tag runs, then sends a consent update whenever the visitor chooses — and on every later page load once they have.

All four v2 consent types are covered: ad_storage, ad_user_data, ad_personalization and analytics_storage.

Available from version 1.0.0.

Render <ConsentMode /> in <head>, above any Google snippet. Consent Mode requires the default to be set before a Google tag loads, which is why this is a separate component rather than part of <ConsentBanner /> (which renders in <body>):

src/layouts/Layout.astro
---
import ConsentBanner from 'astro-cookie-consent/ConsentBanner.astro';
import ConsentMode from 'astro-cookie-consent/ConsentMode.astro';
---
<html>
<head>
<ConsentMode
mapping={{
analytics: ['analytics_storage'],
marketing: ['ad_storage', 'ad_user_data', 'ad_personalization'],
}}
/>
<!-- Google snippet goes after this -->
</head>
<body>
<slot />
<ConsentBanner
privacyHref="/privacy"
categories={[
{ id: 'analytics', label: 'Analytics' },
{ id: 'marketing', label: 'Marketing' },
]}
/>
</body>
</html>

mapping connects your banner’s category ids to the Consent Mode types they grant. A type is granted if any accepted category maps to it, and denied otherwise.

With a plain accept/decline banner (no categories), leave mapping out. The default makes that single choice control all four types:

<ConsentMode />

There are two ways to load Google’s tag alongside <ConsentMode />.

Load the Google tag only after consent, with gateScript(). Nothing reaches Google before the visitor accepts:

<script is:inline>
gtag('js', new Date());
gtag('config', 'G-XXXXXXX');
</script>
<script>
import { gateScript } from 'astro-cookie-consent';
gateScript({
src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX',
category: 'analytics',
});
</script>

<ConsentMode /> defines window.gtag, so the queued js and config calls are picked up once gtag.js loads.

Load Google’s standard snippet (or GTM’s) ungated, after <ConsentMode />. While consent is denied, Google tags send cookieless pings, which lets Google model more of your data.

Google Tag Manager reads the same dataLayer, so its built-in consent checks work in either mode.

Prop Default Description
mapping { all: [all 4 types] } Category id → Consent Mode types it grants.
expiryDays 365 Must match <ConsentBanner expiryDays>.
waitForUpdate 500 Milliseconds Google tags wait for a consent update before firing.
adsDataRedaction false Redact ad click identifiers while ad_storage is denied.
urlPassthrough false Pass ad click info through URLs while cookies are denied.
region (everywhere) ISO 3166-2 codes the denied default applies to, e.g. EEA countries only.

Open your site with the browser’s developer tools and type dataLayer in the console. Before choosing, you’ll see a consent / default entry with every mapped type set to denied. After accepting or declining on the banner, a consent / update entry follows with the new state. Google’s Tag Assistant shows the same signals per tag.