Back to the help center

Integrations

GTM advanced setup

Custom triggers, data layer vars, and ordering

Available on the Pro plan and above. See pricing for what each plan includes.

This guide covers advanced Google Tag Manager configuration with GetCookies, including tag firing order, custom consent triggers, data layer variables, hybrid blocker setups, and debugging techniques.

Tag Firing Order (Critical)

The most important aspect of a GTM + consent setup is the order in which tags fire. Get this wrong and trackers will fire before consent.

Required Order

  1. GetCookies CMP tag -- must use the Consent Initialization - All Pages trigger. This is the special trigger that fires before ALL other triggers in GTM, including "All Pages" and "DOM Ready".
  2. Google tags with consent requirements -- GA4, Google Ads, Meta Pixel, etc. These only fire after the corresponding consent type is granted.
  3. Other tags -- Custom HTML tags, conversion pixels, etc.

GTM has a specific trigger firing order:

1. Consent Initialization   ← GetCookies goes here
2. Initialization
3. Page View (All Pages)     ← Google tags go here
4. DOM Ready
5. Window Loaded
6. Custom Events

If you put the GetCookies tag on "All Pages" instead of "Consent Initialization", other tags on "All Pages" may fire simultaneously, before consent defaults are set.

For each tracking tag in GTM:

  1. Open the tag.
  2. Go to Advanced Settings > Consent Settings.
  3. Check Require additional consent for tag to fire.
  4. Add the appropriate consent types:
Tag typeRequired consent types
GA4 Configurationanalytics_storage
GA4 Eventanalytics_storage
Google Ads Conversionad_storage, ad_user_data
Google Ads Remarketingad_storage, ad_user_data, ad_personalization
Meta (Facebook) Pixelad_storage, ad_user_data, ad_personalization
LinkedIn Insightad_storage, ad_user_data
TikTok Pixelad_storage, ad_user_data, ad_personalization
Hotjar / Session recordinganalytics_storage
Intercom / Chat widgetsfunctionality_storage
Custom analyticsanalytics_storage
Custom advertisingad_storage

Create a trigger that fires when a user updates their consent (e.g., to send a custom event to your analytics):

  1. Go to Triggers > New.
  2. Choose Custom Event.
  3. Set the event name to: cookie_consent_update
  4. Save.

Use this trigger on tags that should fire only when consent changes (e.g., a custom GA4 event that records the consent action).

Category-Specific Triggers

To fire a tag only when a specific consent category is granted:

  1. Create a Custom Event trigger with event name cookie_consent_update.
  2. Add a condition: use a Data Layer Variable (see below) to check the specific category.

Example: Fire a tag only when marketing consent is granted:

  • Trigger: Custom Event = cookie_consent_update
  • Condition: DLV - cookie_consent.marketing equals true

Data Layer Variables

GetCookies pushes consent data to the GTM data layer. Create these variables to use consent state in your triggers and tags:

Setting Up Data Layer Variables

  1. Go to Variables > New > Data Layer Variable.
  2. Create these variables:
Variable nameData Layer Variable NameReturns
DLV - cookie_consent.analyticscookie_consent.analyticstrue/false
DLV - cookie_consent.marketingcookie_consent.marketingtrue/false
DLV - cookie_consent.preferencescookie_consent.preferencestrue/false
DLV - cookie_consent.necessarycookie_consent.necessarytrue (always)

Using Data Layer Variables in Tag Conditions

You can use these variables as firing conditions on any tag:

  1. Open a tag.
  2. In the trigger, click Add Exception or edit the trigger conditions.
  3. Add a condition: DLV - cookie_consent.marketing equals true.

This is useful for Custom HTML tags that do not support GTM's built-in consent settings.

Hybrid Setup: Blocker + GTM

For maximum pre-consent blocking, combine the GetCookies synchronous blocker with GTM:

Script Order in <head>

html
<!-- 1. GetCookies blocker (FIRST - blocks hard-coded scripts) -->
<script src="https://app.getcookies.co/api/v1/widget/blocker.js"></script>

<!-- 2. Google Tag Manager (SECOND) -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXX');</script>

<!-- 3. Any other scripts come after -->

How the Hybrid Works

  1. blocker.js loads synchronously and immediately pauses any hard-coded tracking scripts on the page (scripts with known tracking domains).
  2. GTM loads and the GetCookies CMP tag fires at Consent Initialization, setting consent defaults to "denied".
  3. The GetCookies widget loads (either via GTM Custom HTML tag or directly).
  4. When the user consents, both the blocker and GTM consent states update simultaneously.
  5. Hard-coded scripts unblock and GTM tags fire.

When to Use the Hybrid

  • You have scripts hard-coded in your HTML that you cannot move to GTM.
  • You need to block scripts that load before GTM initializes.
  • Your site has third-party embeds (e.g., YouTube, social widgets) that set cookies on load.

For Custom HTML tags in GTM that do not integrate with Consent Mode natively:

  1. Open the Custom HTML tag.
  2. Go to Advanced Settings > Consent Settings.
  3. Require the appropriate consent type.
  4. GTM will hold the tag until consent is granted.

If you need more granular control inside a Custom HTML tag:

html
<script>
(function() {
    // Check if user has consented to marketing
    var consent = window.GetCookies ? window.GetCookies.getConsent() : null;
    if (consent && consent.choices && consent.choices.marketing) {
        // Initialize your marketing tool here
    }
})();
</script>

Tag Sequencing

For tags that depend on other tags (e.g., a conversion tag that needs GA4 to initialize first):

  1. Open the dependent tag.
  2. Go to Advanced Settings > Tag Sequencing.
  3. Check Fire a tag before [this tag] fires and select the prerequisite tag.
  4. Both tags still need their own consent requirements.

Server-Side Tagging

If you use GTM Server-Side:

  1. The client-side GetCookies CMP handles consent on the browser.
  2. The consent state is included in the event data sent to your server-side container.
  3. Server-side tags can check consent state from the event data before processing.
  4. This ensures server-side tags also respect user consent choices.

Debugging

GTM Preview Mode

  1. Open GTM and click Preview.
  2. Enter your site URL.
  3. In the debug panel, check:
  • Consent Initialization phase: GetCookies CMP tag should fire here.
  • Tags Fired vs Tags Not Fired: tracking tags should be in "Not Fired" before consent.
  • Consent tab: shows the current consent state for each type.
  1. Interact with the consent banner and verify tags move from "Not Fired" to "Fired" (or stay blocked if consent was denied).

Common Debugging Issues

ProblemCauseFix
All tags fire immediatelyGetCookies tag not on Consent Initialization triggerChange trigger to "Consent Initialization - All Pages"
Tags never fire after consentConsent types do not matchVerify the consent type strings match exactly (e.g., analytics_storage not analytics)
Consent state resets on navigationlocalStorage blocked or clearedCheck if the browser blocks localStorage; verify the consent cookie persists
Some tags fire, others do notMixed consent requirementsCheck each tag's consent settings individually
GetCookies tag shows as "Blocked"Another CMP or consent tool conflictingRemove any other consent management tools

Console Debugging

Open Chrome DevTools > Console and look for:

GetCookies: Consent defaults set {ad_storage: "denied", analytics_storage: "denied", ...}
GetCookies: Consent updated by user {ad_storage: "granted", analytics_storage: "granted", ...}

If these messages do not appear, verify the GetCookies script is loading correctly and the Domain ID is valid.

Still stuck?

Email [email protected] with your domain and what you tried. Signed-in customers can also open a ticket from the dashboard.