Skip to main content

Setting Up Google Consent Mode with the Full Fabric CMP

This guide walks you through configuring your own Google Tag Manager (GTM) container so that it correctly respects the consent choices collected by the Full Fabric cookie consent banner (CMP).

This guide walks you through configuring your own Google Tag Manager (GTM) container so that it correctly respects the consent choices collected by the Full Fabric cookie consent banner (CMP). It covers all seven Google consent types, including functionality_storage and personalization_storage, which are commonly missed in simpler Consent Mode setups.

Who this is for

Any Full Fabric customer who runs their own GTM container on their site and wants Google tags (Google Analytics, Google Ads, Floodlight, etc.) to fire, or not fire, based on the consent choices visitors actually make in the Full Fabric cookie banner.

What this achieves

Without this setup, GTM has no way of knowing what a visitor chose in the Full Fabric cookie banner. Tags either fire unconditionally regardless of consent, or default to a fully denied state and never update. This guide connects the two, so:

  • Visitors who accept Analytical cookies get analytics_storage granted.

  • Visitors who accept Advertising cookies get ad_storage, ad_user_data, and ad_personalization granted.

  • Visitors who accept Functional cookies get functionality_storage and personalization_storage granted.

  • Everything else defaults to denied until the visitor makes a choice.

Before you start

You'll need:

  • Edit access to your GTM container.

  • The Full Fabric cookie banner already live on your site (this guide assumes the standard Full Fabric CMP, which stores consent choices under the cookies-acceptance key in the browser's localStorage).

  • About 20 to 30 minutes.

You do not need to write any custom JavaScript on your own site. Everything below is configured inside GTM itself.

Step 1: Import the Full Fabric Consent Mode template

Rather than building the tag template from scratch, download the pre-built template file and import it directly. This avoids the manual permissions setup entirely, the file already includes everything it needs.

  1. In GTM, go to Templates in the left sidebar.

  2. Under Tag Templates, click New.

  3. Click the three-dot menu in the top right corner of the template editor and choose Import.

  4. Select the .tpl file you downloaded.

  5. Click Save. The template arrives named Full Fabric Consent Mode, with its code and all required permissions already configured, nothing further to check or add here.

If you'd rather build it manually, or want to see exactly what the imported file contains, the full source code and permission list are in the Appendix at the end of this guide.

Step 2: Add the small bridge tag

GTM's tag templates can't read localStorage directly for security reasons, so a very small helper tag is needed to make the value available. This is the only piece of custom code you'll add outside the template itself.

  1. Go to Tags, click New.

  2. Name it Consent Bridge.

  3. Tag Configuration, choose Custom HTML.

  4. Paste in:

<script>   
window.ffConsentCookie = window.localStorage.getItem('cookies-acceptance');
</script>
  1. Under Triggering, click the pencil icon and select Consent Initialization - All Pages. If this trigger doesn't exist yet in your container, create it: New Trigger, choose Initialization - Consent Initialization, name it accordingly.

  2. Under Advanced Settings set Consent Settings to No additional consent required.

  3. Save the tag.

Step 3: Add the consent template tag

  1. Go to Tags, click New.

  2. Name it Full Fabric Consent Mode.

  3. Tag Configuration, choose your new Full Fabric Consent Mode template (it'll appear under Custom templates).

  4. Under Advanced Settings set Consent Settings to No additional consent required.

  5. Under Triggering, select the same Consent Initialization - All Pages trigger used in Step 2.

  6. Save the tag.

Step 4: Tell your other tags to respect consent

This step is easy to miss. Adding the tag above sets the consent state, but each of your other tags (Google Analytics, Google Ads, etc.) needs to be told to actually check it.

For each relevant tag:

  1. Open the tag.

  2. Scroll to Advanced Settings, then Consent Settings.

  3. Under Additional consent checks, select Require additional consent for tag to fire.

  4. Add the relevant consent type(s), for example analytics_storage for a GA4 tag, or ad_storage and ad_user_data for a Google Ads conversion tag.

  5. Save.

Google's built in GA4 and Google Ads tag types usually already check some consent types by default (visible without needing to add anything), but it's worth confirming per tag rather than assuming.

Testing your setup

  1. In GTM, click Preview.

  2. Load your site in the Preview-connected tab.

  3. In Tag Assistant, click the Consent tab. You should see all seven consent types listed, with "On-page default" showing Denied (except security_storage, which shows Granted).

  4. Click through your cookie banner and accept everything.

  5. Check the Consent tab again. "On-page update" should now show the matching granted/denied state for each type, based on exactly what you accepted.

  6. Try again in a fresh Preview session, this time rejecting Advertising but accepting Functional and Analytical. Confirm ad_storage, ad_user_data, and ad_personalization stay denied while the others show granted.

If everything in step 5 and 6 matches what you'd expect based on your actual banner choices, the integration is working correctly.

Troubleshooting

"Consent not configured" appears in the Consent tab This means the default consent state was never set. Double check the "Full Fabric Consent Mode" tag is firing on the Consent Initialization - All Pages trigger, not the regular "All Pages" trigger.

"On-page update" stays blank even after accepting the banner This usually means the bridge tag isn't finding the cookie. Open your browser's devtools, go to Application, Local Storage, and confirm a cookies-acceptance key exists with a JSON value once you've accepted the banner. If it's under a different key name, update the bridge tag's script (Step 2) to match.

Some categories update, others don't Check the JSON structure of your cookies-acceptance value in Local Storage. It should contain an options object with functional, analytical, and advertising boolean fields. If your CMP configuration uses different field names, you'll need the source code (see Appendix) to adjust the onUserConsent function to match, since the imported template's code isn't editable field by field.

A tag still fires regardless of consent Revisit Step 4 for that specific tag. Consent Settings must be configured individually per tag, setting the overall consent state doesn't automatically gate every tag in the container.

Import fails, or the template appears with errors Confirm you downloaded the .tpl file itself rather than an HTML page (some browsers rename downloads unexpectedly). Re-download and try the import again. If it still fails, the manual build steps in the Appendix are a reliable fallback.

Notes

  • This setup checks consent once per page load.

  • security_storage is hardcoded to granted, since it covers functions like authentication and fraud prevention that don't require consent under GDPR.

Appendix: Manual setup and template source code

Use this section if you'd rather build the template by hand instead of importing the .tpl file, or if you need to see and modify the underlying code (for example, if your CMP uses different category field names).

Creating the template manually

  1. In GTM, go to Templates, Tag Templates, click New.

  2. Click the pencil icon next to the template name and rename it to Full Fabric Consent Mode.

  3. Open the Code tab, delete the boilerplate, and paste in the source code below.

  4. Click Save. You'll see a permissions error the first time, that's expected.

  5. Open the Permissions tab:

    • Under Accesses consent state, click Add consent type and add each of the following with Write checked: ad_storage, ad_user_data, ad_personalization, analytics_storage, functionality_storage, personalization_storage, security_storage.

    • Under Accesses global variables, click Add key, enter ffConsentCookie, and check Read.

  6. Click Save again.

Template source code

javascript

const log = require('logToConsole');
const setDefaultConsentState = require('setDefaultConsentState');
const updateConsentState = require('updateConsentState');
const copyFromWindow = require('copyFromWindow');
const callLater = require('callLater');
const JSON = require('JSON');

const onUserConsent = (options) => {
updateConsentState({
ad_storage: options.advertising ? 'granted' : 'denied',
ad_user_data: options.advertising ? 'granted' : 'denied',
ad_personalization: options.advertising ? 'granted' : 'denied',
analytics_storage: options.analytical ? 'granted' : 'denied',
functionality_storage: options.functional ? 'granted' : 'denied',
personalization_storage: options.functional ? 'granted' : 'denied',
security_storage: 'granted'
});
};

let consentApplied = false;
let pollCount = 0;

const checkConsent = () => {
pollCount = pollCount + 1;

const rawValue = copyFromWindow('ffConsentCookie');

if (rawValue) {
const parsed = JSON.parse(rawValue);
if (parsed && parsed.accepted === true && parsed.options) {
if (!consentApplied) {
consentApplied = true;
onUserConsent(parsed.options);
}
return;
}
}

if (pollCount < 40) {
callLater(checkConsent);
} else {
log('Full Fabric Consent Mode: gave up waiting for a consent decision.');
}
};

const main = (data) => {
setDefaultConsentState({
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
});
checkConsent();
};

main(data);
data.gtmOnSuccess();
Did this answer your question?