Google Tag Manager — Implementation Guide
Step-by-step guide to deploying MineOS CMP with Google Tag Manager, including full Google Consent Mode v2 support.
This guide walks you through deploying MineOS CMP alongside Google Tag Manager (GTM) so that:
- Your visitors see the MineOS consent banner before any non-essential tags fire.
- Google's tags (Analytics 4, Ads, Floodlight, Conversion Linker) automatically respect the visitor's consent via Google Consent Mode v2.
- Non-Google tags in GTM (Meta Pixel, LinkedIn Insight, Hotjar, etc.) only fire after the visitor has consented to the appropriate category.
Two integration paths, used togetherMineOS CMP gives you both at once:
- Google Consent Mode v2 (automatic). MineOS sets the GCM signals (
analytics_storage,ad_storage, etc.) automatically when consent changes. You do nothing in GTM — Google's own tags read these signals natively.- Custom dataLayer events (for non-Google tags). MineOS exposes a JavaScript SDK that fires whenever consent changes. You forward those changes into the dataLayer and use them as GTM triggers for non-Google tags.
Most sites need both. This guide covers each in turn.
Before you start
You will need:
- A published MineOS website with at least one banner and one rule configured. If you haven't done that yet, see Creating and Configuring Banners and Configuring Banner Rules first.
- Your Domain Group ID — found in Consent Management → Websites → Implementation in the MineOS portal.
- Admin access to your Google Tag Manager container.
- A development/staging environment where you can test before publishing to production.
Step 1 — Install MineOS CMP on your site
The MineOS CMP scripts must load before Google Tag Manager and before any other scripts that set cookies. This ensures cookies and trackers can be intercepted from the very first page load.
Add the following snippet to the very top of your site's <head>, before everything else — including GTM:
<head>
<!-- 1. MineOS configuration (loads first, must be synchronous) -->
<script src="https://cmp.mineos.ai/[YOUR-DOMAIN-GROUP-ID]/configuration.js"></script>
<!-- 2. MineOS CMP runtime (loads immediately after configuration) -->
<script src="https://cmp.mineos.ai/cmp.js"></script>
<!-- 3. Google Tag Manager (loads after MineOS) -->
<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-XXXXXXX');</script>
<!-- Rest of your <head> -->
</head>Replace [YOUR-DOMAIN-GROUP-ID] with your ID from the MineOS portal, and GTM-XXXXXXX with your GTM container ID.
Order and loading mode matterMineOS scripts must come before GTM, and must not use
asyncordefer. If they load late or asynchronously, GTM's tags may fire before MineOS can intercept them, leaking cookies before consent.
After deploying this snippet, visit your site. You should see the MineOS banner appear on first load. If you don't, see the Troubleshooting section.
Step 2 — Confirm Google Consent Mode v2 is active
Once MineOS is installed, Google Consent Mode v2 is already working — there's nothing to configure in GTM for this. Here's what's happening behind the scenes:
- On page load, before GTM fires, MineOS sets the initial GCM state to denied for all storage types (assuming an opt-in banner). This tells Google's tags to operate in "cookieless ping" mode until consent is given.
- When the visitor accepts cookies, MineOS calls
gtag('consent', 'update', {...})to flip the relevant GCM signals to granted. - Google's tags (GA4, Google Ads, Floodlight, Conversion Linker) automatically pick up the change and start setting cookies and sending full events.
MineOS → Google Consent Mode mapping
MineOS automatically maps its cookie categories to GCM signals:
| MineOS Category | GCM Signals Set to "granted" on consent |
|---|---|
| Analytics | analytics_storage |
| Marketing | ad_storage, ad_user_data, ad_personalization |
| Functional / Preferences | functionality_storage, personalization_storage |
| Essential / Necessary | security_storage (always granted) |
Verifying GCM is active
- Open your site in a fresh browser session (clear cookies first, or use incognito).
- Open DevTools → Console and run:
window.dataLayer - Look for entries like:
{ 0: 'consent', 1: 'default', 2: { ad_storage: 'denied', analytics_storage: 'denied', ... } } - Now click Accept All in the MineOS banner.
- Run
window.dataLayeragain — you should see a new entry:{ 0: 'consent', 1: 'update', 2: { ad_storage: 'granted', analytics_storage: 'granted', ... } }
If you see both entries, GCM is working correctly. Google's tags will now honor consent automatically.
You don't need the "Consent Initialization" template tagSome CMPs require you to manually add a Consent Mode or Consent Initialization tag in GTM. MineOS handles this for you — adding a duplicate consent-init tag in GTM is unnecessary and can cause race conditions.
Step 3 — Configure GTM consent settings for Google tags
For each Google tag in your GTM container (GA4 Configuration, Google Ads Conversion, Floodlight, etc.), confirm consent settings are set to the defaults:
- In GTM, open the tag.
- Go to Advanced Settings → Consent Settings.
- Leave Built-in Consent Checks as No additional consent required. Google's tags use the GCM signals MineOS already manages.
You do not need to add Additional Consent Checks for Google tags — Consent Mode v2 handles the gating for you. Adding extra checks can prevent Google's "cookieless ping" mode from working, which reduces measurement coverage.
Step 4 — Gate non-Google tags with a dataLayer trigger
For tags that aren't GCM-aware (Meta Pixel, LinkedIn Insight, Hotjar, TikTok Pixel, custom HTML tags, etc.), you need to gate them on a custom trigger.
The cleanest pattern is:
- Use MineOS's SDK to push a
mineos_consent_updateevent into the dataLayer whenever consent changes. - Create a GTM Custom Event trigger that fires on
mineos_consent_update. - Add a condition to that trigger so it only fires when the right category is consented.
Step 4a — Push consent state to the dataLayer
Add this snippet to your site, after the MineOS scripts and after the GTM snippet:
<script>
(function () {
function pushConsentToDataLayer(consent) {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'mineos_consent_update',
mineos_consent: {
necessary: !!(consent && consent.Necessary),
preferences: !!(consent && consent.Preferences),
analytics: !!(consent && consent.Analytics),
marketing: !!(consent && consent.Marketing)
}
});
}
// Wait until MineCMP is ready, then push the current state and
// subscribe to future changes.
function init() {
if (!window.MineCMP || !window.MineCMP.onReady) {
// MineOS not loaded yet — retry shortly. (Should not happen if the
// CMP scripts are placed before this one, as recommended.)
return setTimeout(init, 50);
}
window.MineCMP.onReady(function () {
pushConsentToDataLayer(window.MineCMP.getConsent());
window.MineCMP.onConsentChange(function (newConsent) {
pushConsentToDataLayer(newConsent);
});
});
}
init();
})();
</script>This will:
- Push a
mineos_consent_updateevent on initial page load (once consent is known). - Push another
mineos_consent_updateevent every time the visitor changes their preferences.
Step 4b — Create a GTM trigger for each category
For each cookie category you need to gate tags on (typically Analytics and Marketing), create a custom-event trigger:
- In GTM, go to Triggers → New → Custom Event.
- Event name:
mineos_consent_update - This trigger fires on: Some Custom Events
- Add a condition. For Marketing tags:
mineos_consent.marketing equals true - Name the trigger something like
Consent Granted — Marketingand save it. - Repeat for Analytics:
mineos_consent.analytics equals true
To make the conditions work, you also need to register the dataLayer variables.
Step 4c — Register dataLayer variables in GTM
- In GTM, go to Variables → User-Defined Variables → New → Data Layer Variable.
- Data Layer Variable Name:
mineos_consent.marketing - Data Layer Version: Version 2
- Save as
DL — Marketing Consent. - Repeat for
mineos_consent.analytics,mineos_consent.preferences, andmineos_consent.necessaryas needed.
Step 4d — Attach the trigger to your non-Google tags
For each non-Google tag (e.g. Meta Pixel):
- Open the tag in GTM.
- In the Triggering section, replace the current trigger (typically All Pages) with the matching consent trigger (e.g.
Consent Granted — Marketing). - Save.
The tag will now only fire after the visitor has granted consent for that category.
What about retroactive firing?The script in Step 4a pushes the current consent state on every page load, so when a returning visitor (who already consented previously) lands on your site, the
mineos_consent_updateevent fires immediately and any gated tags fire as expected — without the visitor needing to interact with the banner again.
Step 5 — Add a "Cookie Settings" link to your footer
Visitors need a way to reopen the banner and change their preferences. This is also a regulatory requirement in many jurisdictions.
Add a link or button to your site footer:
<a href="#" onclick="MineCMP.show('second'); return false;">Cookie Settings</a>This calls MineCMP.show('second'), which reopens the banner directly to the preferences view (second layer). The visitor's previous choices are pre-selected, and they can update them and save.
Step 6 — Test the integration
Before publishing to production, verify the integration end-to-end on staging.
Test 1 — Banner appears on first visit
- Open your site in an incognito window.
- The MineOS banner should appear immediately.
- Open DevTools → Application → Cookies. You should see only Essential cookies — no Google Analytics, no Meta Pixel, no other trackers.
Test 2 — Accepting consent fires tags
- With DevTools open, click Accept All in the banner.
- In the Cookies panel, you should now see
_ga,_ga_*, and any other category-appropriate cookies appear. - In the Network tab, filter for
google-analytics.comandgoogletagmanager.com— you should see full GA4 event hits (not the "cookieless ping"gcs=G100form).
Test 3 — Rejecting consent keeps tags off
- Clear your site data and reload.
- Click Reject All in the banner.
- Confirm no non-essential cookies are set.
- For Google tags, you should still see network requests to
google-analytics.com, but withgcs=G100(cookieless pings). This is correct GCM behavior — no cookies, but Google can still model conversions. - Non-Google tags (Meta Pixel, etc.) should not fire at all.
Test 4 — Changing preferences updates tags
- With the banner closed, click your Cookie Settings footer link.
- Toggle Marketing off and click Save Preferences.
- In DevTools → Console, confirm a new entry was pushed to
window.dataLayerwithmineos_consent.marketing: false. - Reload the page — Meta Pixel and other Marketing tags should not fire.
Test 5 — GTM Preview Mode
Use GTM Preview mode for the most thorough check:
- In GTM, click Preview and enter your staging URL.
- Step through the page load → banner interaction → page reload.
- In each step, check the Tags Fired and Tags Not Fired sections to confirm tags are firing only when their consent category is granted.
Troubleshooting
| Symptom | What to check |
|---|---|
| Banner doesn't appear | Confirm configuration.js and cmp.js are both loading (Network tab). Check that the Domain Group ID in the URL is correct. Confirm a Rule matches your test region — see Configuring Banner Rules. |
| Banner appears but tags still fire before consent | Confirm the MineOS scripts are placed before GTM in the HTML, and that neither uses async or defer. |
mineos_consent_update events never appear in the dataLayer | Confirm the snippet from Step 4a is on the page. In the Console, run MineCMP.isReady() — if false, MineOS hasn't initialized; check the Network tab for errors loading configuration.js. |
| GA4 fires before consent (with cookies) | Check that you haven't manually added a gtag('consent', 'default', { ad_storage: 'granted' ... }) call elsewhere on the page. MineOS sets the GCM defaults — any other consent-init code will override it. |
| Non-Google tags don't fire even after consent | In GTM Preview, check the trigger's condition. Make sure the dataLayer variable name in GTM matches exactly (mineos_consent.marketing with the dot is case-sensitive). |
| Tags fire twice | The dataLayer push and your custom trigger may both be firing. Use GTM Preview to see which trigger is causing the duplicate, and remove the redundant one. |
| GCM signals never flip to "granted" | Open DevTools → Console and run MineCMP.getConsent(). If it returns the right consent shape, GCM should be updating. If it returns null, the visitor hasn't made a choice yet. |
Reference — MineOS SDK methods used in this guide
| Method | Purpose |
|---|---|
MineCMP.onReady(callback) | Waits until the CMP has finished initializing |
MineCMP.getConsent() | Returns the current consent state (object with category booleans) or null |
MineCMP.onConsentChange(callback) | Subscribes to future consent changes; callback receives the new state |
MineCMP.show('second') | Opens the banner directly to the preferences (second) layer |
MineCMP.show('first') | Opens the banner to the first layer |
MineCMP.acceptAll() | Programmatically accept all categories (useful in custom UI flows) |
MineCMP.withdrawAll() | Programmatically withdraw all non-essential consent |
For the full SDK reference, see Using the MineOS JavaScript SDK.
Summary
A correctly deployed MineOS + GTM setup looks like this:
- MineOS scripts load first in
<head>, synchronously, before GTM. - Google tags in GTM rely on Consent Mode v2 — MineOS sets it automatically.
- Non-Google tags in GTM are gated on a
mineos_consent_updatecustom event trigger plus a category condition. - A "Cookie Settings" link in your footer lets visitors update their choice at any time.
That's it — your site is now compliant with GDPR, CCPA, and Google's EU consent requirements, with full measurement coverage via Consent Mode v2.
Updated about 2 hours ago
