Cookie Consent¶
Badger has its own cookie banner. On any site with Google Analytics or Hotjar set up, it asks visitors whether they accept analytics cookies, and neither tool loads until they accept. UK law (PECR) requires that consent before analytics cookies are set.
- A site turns it on by applying the Cookie consent banner platform upgrade. It only appears on sites that have Google Analytics or Hotjar, or that hold back tracking code pasted into Site Text (see Tracking code pasted into Site Text). A site without analytics never shows it.
- Visitors choose Accept analytics cookies or Reject analytics cookies. The two buttons look the same, because rejecting must be as easy as accepting.
- A Cookie settings button opens the banner again, so visitors can change their mind at any time. Changing from accept to reject deletes the Google Analytics and Hotjar cookies.
- When the cookies a site uses change, change the policy version and everyone is asked again.
- A browser that sends Global Privacy Control (a "don't track me" setting in Firefox, Brave and some extensions) is treated as having rejected: the banner doesn't open and analytics stays off. The visitor can still accept through Cookie settings.
- YouTube videos load only when clicked, on every site, whether or not the banner is on. Until then the page shows the block's poster image (chosen from the media library) or a plain dark panel, with a play button. Nothing loads from YouTube or Google, so no cookies are set for visitors who don't watch. A line under each video says "Plays from YouTube, which may set cookies", with a link to the cookie policy. It's left out for a visitor who has accepted cookies on a site with the banner on.
- Every choice is logged as evidence of consent, without recording who made it (see The consent log).
Strictly necessary cookies never wait for consent: the basket, sign-in and session cookies, and Stripe's fraud-prevention cookies.
Setting it up¶
- Remove any other consent tool (such as Cookiebot). Remove tracking code pasted into Site Text or an HTML block, or mark it so the banner holds it back (see below).
- Apply Cookie consent banner under Settings → Platform upgrades. It turns the banner on and, if the site has no policy version yet, sets it to today's date.
- Set Cookie Policy Page to the page that explains your cookies.
The settings are under Settings → Store → Cookie consent:
| Setting | What it does |
|---|---|
Ask for Cookie Consent (cookie-consent-enabled) |
Off until the platform upgrade turns it on. Leave it off if the site uses its own consent tool, such as Cookiebot. |
Cookie Policy Version (cookie-consent-version) |
Any label for the current cookie policy, such as its date. Change it when the cookies you use change, and every visitor is asked again. |
Cookie Policy Page (cookie-policy-url) |
Where the banner's "Read our Cookie Policy" link goes, such as /p/cookies. Empty uses the Privacy Policy URL from the legal entity settings, or shows no link if that's empty too. |
Hold Back Pasted Tracking Code (cookie-consent-pasted-scripts) |
Turn on when the site's only tracking is code pasted into Site Text and marked as below. The banner then appears even though Google Analytics and Hotjar aren't set up in Badger. |
Putting "Cookie settings" in your footer¶
By default a small Cookie settings button appears at the very bottom of every page. To put it
with your other footer links instead, add a link to #cookie-settings (for example
<a href="#cookie-settings">Cookie settings</a> in the footer's Site Text). Clicking it opens the
banner, and the default button then stays hidden.
Wording¶
The banner text comes from the cookieConsent.* messages, so a site can change it through Site Text
like any other storefront message.
Tracking code pasted into Site Text¶
The banner holds back the Google Analytics and Hotjar extensions by itself. A tracking script pasted
straight into Site Text or an HTML block loads for everyone unless you mark it. Change its type to
text/plain and add data-badger-consent="analytics":
<!-- before -->
<script async src="https://example-tracker.com/t.js"></script>
<script>startTracking();</script>
<!-- after -->
<script type="text/plain" data-badger-consent="analytics" async src="https://example-tracker.com/t.js"></script>
<script type="text/plain" data-badger-consent="analytics">startTracking();</script>
The browser doesn't run a text/plain script. Once a visitor has accepted, the banner's script
swaps each marked script for a working copy, in page order. Visitors who reject or haven't chosen
never run it.
The marked code runs only where the banner is active. On a site with no Google Analytics or Hotjar set up in Badger, turn on Hold Back Pasted Tracking Code, or the marked code never runs.
Using the extensions is still better where one exists: the server leaves their scripts out of the page entirely.
How it works¶
The visitor's choice¶
The choice lives in the visitor's bdgr_consent cookie for 12 months. The cookie holds:
- a random consent id
- whether they accepted analytics
- when they chose
- the policy version they answered
The server reads it on every page:
GoogleAnalyticsExtensionandHotjarExtensionrender nothing unless the visitor has accepted the current version. The tracking scripts aren't in the page at all, rather than being present but disabled.CookieConsentExtension, a global extension in theanalyticsslot that every theme's footer renders, shows the banner open when the visitor hasn't answered the current version. Otherwise it renders closed, ready for Cookie settings to open it.
A choice for an older version counts as no choice, so the banner opens and analytics stays off.
The banner also carries data-analytics="true|false", the same answer, for switching on marked
pasted scripts. A visitor who hasn't chosen but whose browser sends Sec-GPC: 1 (Global Privacy
Control) gets the banner closed rather than open. With no choice recorded, analytics stays off.
When a visitor clicks Accept or Reject, the page posts to POST /api/cookie-consent
({"analytics": true}). The endpoint logs the choice, sets the cookie, and the page reloads. It
accepts JSON only, so another website can't accept cookies on a visitor's behalf.
The consent log¶
Each choice adds an entry to the cookieConsentLog collection. An entry holds:
- the consent id
- the site
- the policy version
- the answer
- the time
It deliberately holds no user id, IP address or browser details. It identifies no one, so it needs no erasure handling and doesn't appear in Subject Access Request packs. Mongo deletes each entry after 400 days, a little longer than the cookie lasts.
To show that a particular visitor consented, take the consent id from their bdgr_consent cookie
(the first part of the value, before the first .) and look up its entries. The log also gives
accept and reject counts for each policy version.
If the log can't be written, the visitor's choice still takes effect through their cookie.
Classes¶
| Class | Role |
|---|---|
CookieConsentService / CookieConsentServiceImpl |
Whether the site asks, whether a choice allows analytics, recording a choice (commerce-core/.../consent/) |
CookieConsentCookie |
Reads and writes the bdgr_consent cookie |
CookieConsentRecord |
One consent log entry, with its 400-day TTL |
CookieConsentExtension |
The banner (commerce-core/.../extensions/consent/) |
CookieConsentController |
POST /api/cookie-consent (web-mvc) |
CookieConsentUpgrade |
The platform upgrade that turns the banner on for a site |
YoutubeVideoExtension + youtube-facade.js |
Click-to-load YouTube: the poster image or a plain panel until the visitor clicks, then the youtube-nocookie.com player |
extensions/cookieConsentExtension/banner.html |
One template for every theme, styled by themes/shared/css/extensions/cookieConsent/cookie-consent.css |
Limits¶
- The banner appears wherever storefront extensions render: pages, products, collections, search and checkout. Pages without extensions, such as sign-in, don't show it, but analytics doesn't load on them either.
- Global Privacy Control is read from the request header. Browsers that only expose it to scripts
(
navigator.globalPrivacyControl) aren't detected. - Consent is per browser. A shopper is asked again on a new device or browser.
- There's one choice, analytics. A site that adds advertising or remarketing tags needs a separate marketing choice, which isn't built yet.