How to set up Google Tag Manager with Cookiequiet
Load Cookiequiet in the page head above the Google Tag Manager snippet with data-consent-mode="1", and put Google's default consent block between the two so the container never runs without a default. Google tags in the container then follow Consent Mode v2 through their built-in checks; for other tags, trigger on the cq_consent event with the cq_analytics, cq_marketing and cq_functional flags.Steps
The order of the scripts in the head
Google's rule for Consent Mode is simple: the default consent state must be set before the Google tag or the container loads, otherwise the defaults do not work. Cookiequiet pushes the denied defaults as soon as it runs when the snippet carries data-consent-mode="1". Because the snippet is deferred and the container loads asynchronously, a long page could let the container run first; the standard fix, which Google documents, is an inline default block right before the container. Your head then reads:
html<!-- 1. Cookiequiet --><script src="https://cookiequiet.com/cq.js" data-site="YOUR_SITE_KEY" data-consent-mode="1" data-auto-block="1" defer></script><!-- 2. Default consent state, before the container --><script>window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);}gtag('consent', 'default', {ad_storage: 'denied',ad_user_data: 'denied',ad_personalization: 'denied',analytics_storage: 'denied',functionality_storage: 'denied',personalization_storage: 'denied',security_storage: 'granted',wait_for_update: 500});</script><!-- 3. Google Tag Manager, as high in the head as possible --><script>(function(w,d,s,l,i){ /* the container snippet from Admin, Install Google Tag Manager */ })(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
The noscript part of the container stays right after the opening body tag. Cookiequiet does not hold the container itself: Google Tag Manager sets no cookies, and loading it with denied defaults is what Google calls the advanced implementation, the one that produces cookieless pings and modelled data.
What Cookiequiet sends to the data layer
gtag('consent', 'default', ...): every type denied exceptsecurity_storage, withwait_for_update: 500, pushed when the snippet runs.gtag('consent', 'update', ...)after each choice, and on every page load where a choice is stored: analytics givesanalytics_storage; marketing givesad_storage,ad_user_dataandad_personalization; functional givesfunctionality_storageandpersonalization_storage.- A data layer event
cq_consentwith three booleans,cq_functional,cq_analyticsandcq_marketing, pushed at the same moments.
Visitors outside the regions where the banner is shown (if you use geo-targeting) get every category granted at once, so the update reaches the container on their first page view too.
How to configure the container
- Consent Overview. In Admin, then Container Settings, enable Consent Overview. The shield icon in the Tags list sorts tags into "consent configured" and "consent not configured" and lets you edit several at once.
- Google tags. Google Analytics, Google Ads, Floodlight and Conversion Linker have built-in consent checks: they read the consent state and adjust what they send. Keep their usual triggers; see the Google Analytics 4 and Google Ads guides for what each signal does.
- Other tags. For Hotjar, LinkedIn Insight, TikTok, the Meta Pixel template, Microsoft Clarity and similar tags, use the
cq_consentevent:
- Variables: create three Data Layer Variables, cq_analytics, cq_marketing, cq_functional. - Triggers: create a Custom Event trigger with the event name cq_consent, Some Custom Events, condition cq_marketing equals true (and the same for the other two). - Tags: replace All Pages with the matching trigger and set Tag firing options to Once per page, since the event can fire twice on a page where the visitor changes their mind. - Optionally, under Advanced Settings, then Consent Settings, select Require additional consent for tag to fire and add ad_storage or analytics_storage: Tag Manager then refuses to fire the tag while that type is denied, whatever the trigger.
- Event tags. Conversion or form tags that fire on their own events keep their triggers; give them the additional consent check instead, so they are skipped while consent is denied.
A Consent Initialization trigger is meant for a consent tool loaded from inside the container. Cookiequiet is loaded from the page, which is more reliable: a script injected by a Custom HTML tag loads asynchronously, and the tags on Initialization and All Pages do not wait for it.
How to test
- Open Preview in Tag Manager and load your site. In Tag Assistant, open the Consent tab: on the first event, every type reads denied, with the default and the update rows listed.
- Click Accept all: a
cq_consentevent appears in the summary, the Consent tab shows the update as granted, and the tags attached to the triggers fire. - Reload in a private window and click Reject all: no
cq_consent-triggered tag fires, and the browser has no_gaor_fbpcookie. - Publish the container. The consent log in the Cookiequiet dashboard records both choices.
Limits worth knowing
- Cookiequiet is not a Google-certified CMP for the IAB TCF: sites showing AdSense, Ad Manager or AdMob ads to visitors in the EEA, the UK or Switzerland need a certified CMP for those ads. Conversion tracking, analytics and pixels work with the Consent Mode integration described here.
- Tags fired from a server-side container follow the same client-side signals; the data layer event and the consent commands reach it through the web container.
- Microsoft UET consent is available on request and follows the marketing category, which matters if the container also loads Microsoft Advertising.