ConsentChecks · implementer guide

Installing ConsentChecks

How to put the consent banner on a site, how consent reaches GTM and every common tracking pixel — Meta, TikTok, LinkedIn, Hotjar and more — and the checklist that proves it works before launch.

1 · Install — 5 minutes

  1. Copy the embed code. Dashboard → Sites → your site → Embed code:

    <!-- Place above your GTM snippet -->
    <script src="https://app.consentchecks.com/cc.js"
            data-site="YOUR_SITE_KEY"></script>
  2. Paste it in the page <head>, above the GTM snippet. The order is load-bearing: ConsentChecks must set consent defaults before GTM boots. Don't add async or defer.

  3. Register every hostname under Dashboard → site → Domains. www.example.com and example.com are separate entries. Consent logging is rejected (HTTP 400) from unregistered hostnames.

    #1 cause of "I accepted but see no logs."If the www variant isn't registered, every consent click is dropped by design.
  4. Remove any other consent tool (iubenda, CookieYes, OneTrust…). Two CMPs fight over the same Google signals.

  5. Purge page caches (WP Engine, LiteSpeed, Cloudflare APO…). Cached HTML won't contain the snippet.

2 · How consent reaches GTM

Three mechanisms run at once. Use whichever fits each tag.

A — Google Consent Mode v2 (automatic)

Before GTM loads, ConsentChecks sets consent defaults: denied in opt-in regions (EU/UK/CH), granted under the US opt-out model until the visitor objects. When a visitor chooses, category keys map to Google's signals:

Category keyGoogle signals
analyticsanalytics_storage
marketingad_storage · ad_user_data · ad_personalization
preferencespersonalization_storage
always grantedfunctionality_storage · security_storage

GA4, Google Ads and Floodlight obey these natively — no GTM changes needed. Denied analytics_storage means GA4 runs cookieless; granted means full tracking.

The keys are a contract.Only categories keyed exactly analytics, marketing or preferences drive Google signals. Custom categories still work with B and C.

B — dataLayer events (for everything else)

On every consent decision ConsentChecks pushes cc_consent_update (with cc_granted / cc_denied arrays) plus one cc_<category>_granted event per granted category.

Recipe — gate a Meta pixel on marketing consent:

  1. GTM → Triggers → New → Custom Event → event name cc_marketing_granted → fires on All Custom Events.

  2. Open the pixel's tag → Triggering → replace All Pages with this trigger.

  3. Done — the tag cannot fire until marketing is granted. The event re-fires on every page load for returning visitors, so page-view pixels keep working.

Want GA4 fully silent on reject (not even cookieless pings)? Tag → Consent Settings → Require additional consent → analytics_storage, or use the trigger recipe.

C — outside GTM entirely

3 · Platform recipes

The pattern is always the same: pick the category, then gate the tag through GTM (custom-event trigger) or through ConsentChecks itself (Custom scripts).

PlatformCategoryHow to gate it
GA4 · Google Ads · Floodlightanalytics / marketingNothing to do — Consent Mode v2 governs them automatically (GTM or direct gtag.js, kept below the ConsentChecks script). For full silence on reject, gate with cc_analytics_granted or the tag's Require additional consent.
Meta (Facebook) PixelmarketingIn GTM: Custom Event trigger cc_marketing_granted on the pixel tags. Hardcoded: move the base pixel into Dashboard → Custom scripts under marketing. Advanced: fbq('consent','revoke') at load + 'grant' from a gated script, only if you need Meta's limited-data mode.
TikTok PixelmarketingGTM trigger on cc_marketing_granted, or base snippet as a Custom script.
LinkedIn InsightmarketingSame: GTM trigger or Custom script.
Pinterest · X · SnapmarketingSame pattern.
Hotjar · MS ClarityanalyticsSession recording counts as analytics: cc_analytics_granted trigger, or Custom script under analytics.
Chat widgets (Intercom, Drift, Tawk…)preferences / customCustom script under preferences, or a dedicated category (e.g. chat). Custom keys don't drive Google signals but gate scripts, events and markup the same.

Anything else: decide the category (advertises → marketing, measures → analytics, personalizes → preferences); in GTM use a cc_<category>_granted trigger; hardcoded snippets move into Custom scripts; visible UI can be wrapped in <div data-cc-show="…" hidden>.

4 · US specifics

5 · Verify before launch — 10 minutes

  1. Snippet placement. View source: cc.js above GTM, no async/defer. Missing → page cache or publish state.

  2. Banner shows. Fresh incognito window → banner appears (US visitors see it too).

  3. Consent round-trip. DevTools → Network → filter cc/log → Accept all → POST returns 204. A 400 means the hostname isn't registered. Then document.cookie contains cc_consent_<sitekey>; reload → no banner.

  4. Log recorded. Dashboard → Logs: the accept appears within seconds.

  5. Google signals. Connect tagassistant.google.com → Consent tab: denied before the choice, granted after Accept; gated tags fire; cc_* events visible in the stream.

  6. Reject path. Fresh incognito → Reject all: signals stay denied, gated tags silent, reject_all row in Logs.

  7. GPC. Firefox → about:config → privacy.globalprivacycontrol.enabled = true → visit: a gpc_optout row appears with no click.

  8. Re-open. Console: window.ConsentChecks.open() shows preferences; a changed choice logs an update action. getConsent() prints granted keys.

  9. Pixels. Install the platform's helper extension (Meta Pixel Helper, TikTok Pixel Helper): the pixel is absent before consent and fires after Accept.

6 · Troubleshooting

SymptomCause → fix
No bannerSnippet not in served HTML (cache / unpublished), visitor already has a consent cookie (use incognito), or geo mode none
Accepts but Logs stay empty400 origin not allowed — register the exact hostname (www and apex separately) under site → Domains
Tags fire before any choiceSnippet below GTM, or tag lacks a consent check / cc_* trigger
Banner reappears every visitCookies blocked in that browser, or policy_version was bumped (that re-prompt is intentional)
New banner settings not liveCloudflare still caching cc.js (purge it) and/or the site's own page cache
GA4 shows traffic from rejectersConsent Mode's cookieless pings (by design, no cookies). For full silence, gate GA4 with cc_analytics_granted