# 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.

Source: https://cookiequiet.com/platforms/google-tag-manager
Published: 2026-10-20
Publisher: Cookiequiet

## Steps

1. **Order the head: Cookiequiet, defaults, container** Paste the Cookiequiet snippet first in the head, then Google's default consent block (every type denied except security_storage, with wait_for_update 500), then the GTM container snippet as high in the head as possible. The noscript part stays right after the opening body tag.
2. **Enable the consent overview** In Tag Manager, go to Admin, then Container Settings, and enable Consent Overview. The shield icon in the Tags list then shows which tags have consent configured.
3. **Leave Google tags on their built-in checks** Google Analytics, Google Ads, Floodlight and Conversion Linker tags adjust to the consent state on their own. They need no extra trigger: Cookiequiet sends the consent update when the visitor chooses.
4. **Create the data layer variables** Under Variables, create three Data Layer Variables named cq_analytics, cq_marketing and cq_functional, reading the keys of the same names.
5. **Create the cq_consent triggers** Under Triggers, create a Custom Event trigger with the event name cq_consent, firing on Some Custom Events where cq_analytics equals true; repeat for cq_marketing and cq_functional.
6. **Attach the triggers to non-Google tags** Give Hotjar, LinkedIn, TikTok, Meta Pixel and other non-Google tags the matching cq_consent trigger instead of All Pages, set them to fire once per page, and optionally add Require additional consent for tag to fire in their consent settings.
7. **Preview and test** Open Preview (Tag Assistant). On load, the Consent tab shows every type denied; after Accept all it shows the update and the tags fire; after Reject all, no _ga or _fbp cookie is set. Publish the container.

## 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 except `security_storage`, with `wait_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 gives `analytics_storage`; marketing gives `ad_storage`, `ad_user_data` and `ad_personalization`; functional gives `functionality_storage` and `personalization_storage`.
- A data layer event `cq_consent` with three booleans, `cq_functional`, `cq_analytics` and `cq_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

1. **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.
2. **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](/platforms/google-analytics-4) and [Google Ads](/platforms/google-ads) guides for what each signal does.
3. **Other tags.** For Hotjar, LinkedIn Insight, TikTok, the Meta Pixel template, Microsoft Clarity and similar tags, use the `cq_consent` event:
   - **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.
4. **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

1. 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.
2. Click **Accept all**: a `cq_consent` event appears in the summary, the Consent tab shows the update as granted, and the tags attached to the triggers fire.
3. Reload in a private window and click **Reject all**: no `cq_consent`-triggered tag fires, and the browser has no `_ga` or `_fbp` cookie.
4. **Publish** the container. The [consent log](/guides/how-long-to-keep-consent-records) 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.

## Questions

### Is there a Cookiequiet template for Google Tag Manager?

No, and none is needed. Cookiequiet talks to the container with Google's own consent commands and a data layer event, so you configure the container with the built-in consent settings, Data Layer Variables and a Custom Event trigger.

### Can I load Cookiequiet from a Custom HTML tag on the Consent Initialization trigger?

You can, but it is less reliable: a script injected by a tag loads asynchronously and the other tags do not wait for it. Load the snippet from the page head above the container, with the inline default block, as shown above.

### Why does the consent overview say some tags have no consent configured?

Because you have not told Tag Manager which consent type they need. Google tags have built-in checks and need nothing; for the others, attach a cq_consent trigger and, if you want a hard stop, add Require additional consent for tag to fire.

### Should I block the whole container until consent instead?

Google calls that the basic implementation: nothing is sent before consent, but Google cannot model the missing data. The advanced implementation above loads the container with denied defaults; Google tags send cookieless pings and Google models conversions and behaviour. Both are valid; the choice is yours.

### A tag still fires before consent. What should I check?

In Tag Assistant, look at the event that fired it. If it fired on Container Loaded or All Pages, it needs the cq_consent trigger or the additional consent check. If the Consent tab shows no default on the first event, the default block is missing or sits below the container.

## Sources

- [Google Tag Manager Help: Consent mode in Tag Manager](https://support.google.com/tagmanager/answer/10718549)
- [Google: Set up consent mode on websites](https://developers.google.com/tag-platform/security/guides/consent)
- [Google Tag Manager Help: Custom event trigger](https://support.google.com/tagmanager/answer/7679219)
- [Google Tag Manager Help: Install a web container](https://support.google.com/tagmanager/answer/14847097)
