We use cookies to improve your experience on our website. By clicking “Accept all’, you agree to the use of all cookies. Privacy policy
November 26, 2025

How to connect Finsweet Cookie Consent to Google Consent Mode V2

Legal
Tips & Tricks
by Corbinian Buchberger
Corbinian Buchberger

Key takeaways

  • Finsweet Cookie Consent V1 does not block analytics by default, so it is not GDPR compliant without extra setup.
  • Google Consent Mode V2 requires a deny by default state before any tag loads.
  • You need the default consent script both in the site head and in a GTM Consent Initialization tag.
  • Finsweet must run in opt in mode so analytics and marketing are off until the user chooses.
  • A small bridge script is required to translate Finsweet categories into Google consent signals.
  • GA4 and Microsoft Clarity must be set to require analytics_storage inside GTM.
  • GTM will automatically block or allow tags based on the updated consent signals.
  • The script order in the head matters: default consent script → GTM → Finsweet → bridge script.
  • You should test the setup in GTM Preview Mode to confirm that GA4 and Clarity fire only after consent.
  • This setup makes Finsweet Cookie Consent V1 fully compatible with Consent Mode V2 and GDPR expectations.

If your business operates in the EU, or you have EU customers, and you are still using Finsweet’s default cookie consent, your site may not be GDPR compliant. Many setups let analytics and tracking run before a user actually gives consent. That risks fines and it also pollutes your data with non-consenting users.

This guide shows the exact, copy-paste steps to fix that. You will get a small bridge script to add to your site head, the precise GTM changes for GA4 and Microsoft Clarity, and a short testing checklist. Follow these steps, and your site will only run analytics after a user explicitly opts in, keeping you compliant and keeping your analytics accurate.

Ready? Let’s begin

Why this matters

Before we set this up, first let’s understand why you even need this. If your business is in the EU or you have EU customers, getting consent wrong is both a legal and a business risk.

Legal risk. GDPR requires prior consent for nonessential tracking. Supervisory authorities across the EU have issued billions of euros in fines, roughly €5.65 billion as of March 1, 2025, and individual penalties may reach €20 million or 4% of global turnover, whichever is higher.

Bad data. When trackers run before users opt in, your GA4 data includes people who never agreed. That skews conversion rates, funnels, and A/B test results, and makes decisions based on that data riskier.

User trust. People expect control over their data. A clear, working consent flow reduces complaints, lowers support overhead, and helps keep customers confident using your product.

Ad vendors and integrations. Some ad and personalization tools require separate consent flags. If those flags are wrong, you either block needed functionality or collect data you should not.

Auditability. Keeping a clean, auditable consent record makes it easier to show regulators and stakeholders who consented, when, and what they accepted. That is often the fastest way to resolve questions and complaints.

What you need before you start

Quick checklist. Make sure you have these in place before you touch code or GTM.

  • Finsweet Cookie Consent is installed, and the cookie banner works on the site.
  • Access to edit the site head so you can add the bridge script and FsCC attributes.
  • A Google Tag Manager container for the site and permission to publish changes.
  • A GA4 property and measurement ID, or an existing GA4 Configuration tag in GTM.
  • Microsoft Clarity account or any other analytics tags you plan to gate behind consent.
  • A test plan: an incognito browser or a way to clear site cookies and storage for testing.

Quick checks to run now (paste into browser console on the live page)

// check FsCC exists
console.log(!!(window.FsCC && window.FsCC.store && window.FsCC.store.getConsents));

// check GTM dataLayer exists
console.log(Array.isArray(window.dataLayer));

// see if any consent updates already pushed
console.log((window.dataLayer||[]).slice(-30).filter(d => Array.isArray(d) && d[0]==='consent'));

If any of the first two return false, pause and fix that before moving on.

How it works

Before we jump into the technical steps, it helps to understand the flow. Consent Mode V2 basically works like a signal chain. A user makes a choice in the cookie banner, Finsweet stores that choice, and a small bridge script translates it into the Google Consent Mode format that GTM understands.

Here’s the flow -

1. The user sees the cookie banner

The Finsweet Cookie Consent banner shows categories like Essential, Analytics, Marketing, and Personalization. The user accepts all cookies or customizes their preferences.

2. Finsweet stores the user’s preferences

FsCC saves the selected choices in its internal store. Whenever a user accepts cookies or updates preferences, FsCC emits events such as:

  • updateconsents
  • fscc:consentsUpdated

These events tell the rest of the page that consent has changed.

3. The bridge script listens and updates Google Consent Mode

The small bridge script you add in your site head watches Finsweet’s consent store. Whenever FsCC updates, the script translates those choices into the correct Consent Mode keys and pushes them into the dataLayer like this:

['consent', 'update', {
  analytics_storage: 'granted' or 'denied',
  ad_storage: 'granted' or 'denied',
  ad_user_data: 'granted' or 'denied',
  ad_personalization: 'granted' or 'denied',
  personalization_storage: 'granted' or 'denied',
  functionality_storage: 'granted',
  security_storage: 'granted'
}]

This is what tells GTM exactly what the user allowed.

4. GTM updates its internal consent state

Google Tag Manager listens for the consent update event automatically. After receiving it, GTM updates its internal Consent Mode state.

Tags that depend on consent will only fire when the required signals are granted:

  • GA4 requires analytics_storage: granted
  • Microsoft Clarity requires analytics_storage: granted
  • Ad platforms require ad_storage, ad_user_data, and ad_personalization

This ensures no tracking runs unless the user has clearly opted in.

5. Category mapping at a glance

To make everything predictable, we use this consistent mapping:

Finsweet Category Consent Mode Key
Analytics analytics_storage
Marketing ad_storage, ad_user_data, ad_personalization
Personalization personalization_storage
Essential security_storage
(Functionality cookies) functionality_storage (always set to granted)

This is the mapping that gives you a clean, GDPR friendly setup.

6. Why script order matters

Consent Mode V2 depends heavily on the correct loading order. Use this order for a reliable setup:

  1. Default deny script (must run before GTM)
  2. Google Tag Manager script
  3. Finsweet Cookie Consent script (opt-in mode)
  4. Bridge script (immediately under Finsweet)

This ensures:

  • Cookies start in “denied” mode
  • GTM loads in the correct consent state
  • Finsweet updates get passed instantly
  • No tag fires before consent is granted

Setting up GA4 in Google Tag Manager

Let’s set up GA4 so it only runs when a user has allowed analytics cookies.

GA4 needs to be gated behind the analytics_storage consent type. Google Consent Mode V2 requires this, and our bridge script will update this consent flag based on the user’s choices in the Finsweet banner.

Steps to set up GA4

  1. In Google Tag Manager, go to Tags > New.
  2. Name your tag GA4 – Configuration.
  3. Choose Google Analytics: GA4 Configuration as the tag type.
  4. Paste your Measurement ID (G-XXXXXXXX).
  5. Open Consent Settings.
    • Enable “Require additional consent for this tag.”
    • Select analytics_storage.
    • Leave ad_storage unchecked unless you actually use Google Ads.
  6. Scroll down to Triggering and add:
    • Page View (All Pages)
  7. Save the tag.

This setup ensures GA4 runs only when analytics consent is granted. 

Setting up Microsoft Clarity in Google Tag Manager

Clarity counts as analytics, so it also needs to respect the analytics_storage consent flag. The setup is almost identical to GA4, whether you use a built-in Clarity template or a Custom HTML tag.

Steps to set up Clarity (template method)

  1. Go to Tags > New.
  2. Choose the Microsoft Clarity tag template (if available).
  3. Name it Clarity – Tracking.
  4. Paste your Clarity Project ID.
  5. Open Consent Settings.
    • Require analytics_storage.
  6. Under Triggering, add:
    • Page View (All Pages)
  7. Save the tag.

Steps to set up Clarity (Custom HTML method)

If you prefer to paste the script manually:

  1. Go to Tags > New > Custom HTML.
  2. Paste your Clarity script:

<script>
(function(c,l,a,r,i,t,y){
  c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
  t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/YOUR_CLARITY_ID";
  y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
})(window, document, "clarity", "script", "YOUR_CLARITY_ID");
</script>

  1. Open Consent Settings and require analytics_storage.
  2. Add Page View in Triggering.
  3. Save the tag.

This ensures Clarity only loads when analytics consent is granted, and that it starts tracking immediately when a user opts in.

Setting up the Consent Initialization tag in Google Tag Manager

Before connecting Finsweet to Consent Mode, you must set a default consent state inside Google Tag Manager. Google requires this for Consent Mode V2. This ensures GTM blocks all analytics and marketing tags until the user gives permission.

  1. Go to GTM → Tags → New
  2. Name it Consent – Default (Initialization)
  3. Tag Type: Custom HTML
  4. Paste the default consent code:

<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){ dataLayer.push(arguments); }

  gtag('consent', 'default', {
    ad_storage: 'denied',
    analytics_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
    personalization_storage: 'denied',
    functionality_storage: 'granted',
    security_storage: 'granted',
    wait_for_update: 500
  });
</script>

  1. Under Triggering, choose:
    Consent Initialization – All Pages
  2. Save.

This tag must fire before everything else inside GTM. Combined with the head script, it ensures analytics is fully blocked until real consent is granted.

Connecting Finsweet Cookie Consent to Google Consent Mode V2

This is where your cookie banner begins controlling your analytics tags. With this setup, GA4, Microsoft Clarity, and any other marketing tools stay disabled until the user explicitly opts in.

Follow these steps in the exact order.

Step 1: Add the “deny by default” Consent Mode script to your site head

This must be the FIRST script in your head, placed above GTM.

<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){ dataLayer.push(arguments); }

  gtag('consent', 'default', {
    ad_storage: 'denied',
    analytics_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
    personalization_storage: 'denied',
    functionality_storage: 'granted',
    security_storage: 'granted',
    wait_for_update: 500
  });
</script>

This ensures analytics and ads remain completely blocked until consent is granted.

Step 2: Add Google Tag Manager right under the default consent script

Right under the script above, add your GTM container:

<!-- Google Tag Manager -->
<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>
<!-- End Google Tag Manager -->

Then add the noscript version right after your opening <body> tag:

<noscript>
  <iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
  height="0" width="0" style="display:none;visibility:hidden"></iframe>
</noscript>

This ensures GTM loads early enough to receive consent updates.

Step 3: Add Finsweet Cookie Consent in opt-in mode

Right under GTM:

<script async
  src="https://cdn.jsdelivr.net/npm/@finsweet/cookie-consent@1/fs-cc.js"
  fs-cc-mode="opt-in"
  fs-cc-consentmode="true"
  fs-cc-debug="false"></script>

Step 4: Add the bridge script directly under Finsweet

This is the piece that connects Finsweet preferences to Google Consent Mode V2.

<script>
(function(){
  function mapFsToGtm(consents){
    return {
      analytics_storage: consents?.analytics ? 'granted' : 'denied',
      ad_storage: consents?.marketing ? 'granted' : 'denied',
      ad_user_data: consents?.marketing ? 'granted' : 'denied',
      ad_personalization: consents?.marketing ? 'granted' : 'denied',
      personalization_storage: consents?.personalization ? 'granted' : 'denied',
      functionality_storage: 'granted',
      security_storage: consents?.essential ? 'granted' : 'granted'
    };
  }

  function updateConsent(consents){
    var gtmMap = mapFsToGtm(consents || {});
    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push(['consent', 'update', gtmMap]);
  }

  function waitForFsCC(cb){
    if(window.FsCC?.store?.getConsents && window.FsCC?.consentController) return cb();
    var id = setInterval(function(){
      if(window.FsCC?.store?.getConsents && window.FsCC?.consentController){
        clearInterval(id);
        cb();
      }
    }, 100);
  }

  waitForFsCC(function(){
    updateConsent(window.FsCC.store.getConsents());
    window.FsCC.consentController.on('updateconsents', function(){
      updateConsent(window.FsCC.store.getConsents());
    });
    document.addEventListener('fscc:consentsUpdated', function(){
      updateConsent(window.FsCC.store.getConsents());
    });
  });
})();
</script>

Important:

  • This must NOT go inside GTM.
  • Must be in the head.
  • Must sit directly under the Finsweet script.

Step 5: Make sure your GTM Consent Initialization tag fires first

Inside GTM, you already created:

✔ Consent – Default (Initialization)
✔ Trigger: Consent Initialization – All Pages

This must be the only tag using that trigger.

Everything else (GA4, Clarity, marketing tags) must fire on Page View.

Step 6: Publish your site

Once published, the system works automatically:

  • Default = denied
  • User accepts cookies
  • Finsweet updates its store
  • Bridge sends consent updates to the dataLayer
  • GTM updates its internal consent state
  • GA4 + Clarity fire only when allowed

Testing your setup

Before calling your setup complete, run through this quick testing checklist. It confirms that Consent Mode is blocking analytics by default and only allowing them once the user opts in.

Follow these steps in order.

1. Open your site in an incognito window

This ensures you start with no stored cookies and no previous consent state.

2. Open GTM Preview Mode

  1. Go to Tag Manager
  2. Click Preview
  3. Enter your site URL
  4. Click Connect

A debug panel will appear.

3. Check that GA4 and Clarity do NOT fire on page load

In the debug panel:

  • Look at the Tags Fired list
  • GA4 Configuration should not fire
  • Microsoft Clarity should not fire
  • Only the Consent – Default (Initialization) tag should fire at the start

This confirms the deny-by-default script is working.

4. Accept cookies on the banner

Click Accept All in the Finsweet cookie banner.

Within one second, you should see:

  • A new consent update event inside the GTM Preview panel
  • GA4 firing
  • Clarity firing
  • Marketing tags firing (if you have any)

If analytics still doesn’t fire after accepting, something is wrong in the mapping or tag settings.

5. Inspect the dataLayer manually (optional but useful)

Open DevTools → Console and run:

window.dataLayer.slice(-20)

You should see an entry like:

["consent", "update", {
  analytics_storage: "granted",
  ad_storage: "granted",
  ad_user_data: "granted",
  ad_personalization: "granted",
  personalization_storage: "granted",
  functionality_storage: "granted",
  security_storage: "granted"
}]

This confirms the bridge is correctly passing signals to GTM.

6. Reject cookies and reload

  • Reload the page, clear the cookies from browser settings, and confirm:
  • Reconnect the preview mode and connect your site.
  • Reject the cookie this time, and check the tag assistant again.
  • GA4 does not fire
  • Clarity does not fire
  • Marketing tags do not fire
  • Only the Consent Initialization tag fires

This confirms the system respects opt-out behavior.

Your site is now fully GDPR friendly, cleanly connected, and consistent across all future projects.

Conclusion

Getting a cookie banner to actually control your analytics is one of those things that sounds simple but rarely works out of the box. If your business operates in the EU or serves EU customers, you need to make sure analytics scripts do not fire until users give explicit permission.

With this setup, your Finsweet Cookie Consent banner sends real consent signals into Google Tag Manager. GA4, Microsoft Clarity, and any other tracking tags will stay fully blocked until the correct consent is granted, and will start running the moment a user opts in. Your site becomes GDPR friendly, and your analytics stay clean and trustworthy.

This setup is also reliable across projects. Once you understand the flow, you can reuse the same structure for any site that uses Finsweet’s cookie banner and GTM.

And if you need help building a GDPR compliant website in Webflow, our team can support you with a clean, privacy first setup. Book a call and we will walk you through the best approach for your project.

FAQ