Cookie banner compliance: what it must do and common failure points
For website owners who need to decide whether their cookie banner is actually doing the job, not just looking legal. This guide explains what a compliant banner must do in practice, how consent should flow through your site, and the mistakes that commonly break compliance.
TL;DR — A cookie banner is not just a notice; it is a control point that must block non-essential cookies and tracking until the visitor gives valid consent, and it must be as easy to refuse as to accept. The most common fix is to stop analytics, ad tags, and embedded third-party tools from loading before consent, then store and honor the visitor’s choice consistently. Reading time: ~7 min
What it is and where it sits
A cookie banner is the visible part of a broader consent system. Its job is to ask for permission before your site stores or reads non-essential cookies (small browser-stored identifiers) or starts similar tracking technologies such as analytics tags, ad pixels, session replay tools, or embedded third-party media that set identifiers.
From a privacy point of view, the banner sits between the visitor and every optional tracker on the page. It does not replace your privacy policy or cookie policy. It works alongside them:
- Banner: asks for a choice.
- Consent store: records that choice.
- Tag loading logic: decides what scripts, if any, may run.
- Privacy/cookie policy: explains what each category does.
In a typical website request flow, the browser requests a page, your server or hosting platform returns HTML, and then the browser starts loading scripts. The compliance problem appears here: many sites load analytics or ad scripts immediately, then show a banner afterward. By that point, tracking has already started.
A compliant setup changes that flow. The page loads with only strictly necessary code active, the banner appears, and optional tools load only after the visitor opts in.
View as text
[Visitor Browser] ---- 1. GET page ----> [Website] [Website] ---- 2. HTML with banner logic ----> [Visitor Browser] [Visitor Browser] | 3. show choices v [Cookie Banner] [Cookie Banner] ---- 4. save consent ----> [Consent Store] [Cookie Banner] ---- 5a. allow analytics ----> [Tag Loader] [Cookie Banner] ---- 5b. reject analytics ----> [Tag Loader] [Tag Loader] ---- 6. load only allowed tags ----> [Third-Party Tools]
What talks to it:
- Your website frontend (the page code).
- Your tag manager or script loader (tool that injects analytics/marketing scripts).
- Third-party vendors like analytics, advertising, video embeds, chat widgets, and A/B testing tools.
- Sometimes your backend, if consent choices are stored server-side as well as in the browser.
Where it lives:
- Usually in your site’s frontend code, tag manager, or consent management platform.
- Sometimes partly in a server-side template if you render pages on the server.
How it actually works
Here is one realistic example: a marketing site uses essential session cookies, Google Analytics, a Meta pixel, and an embedded YouTube video.
Step-by-step example
- A visitor opens
https://www.example.com/pricing. - The server returns the page HTML. That HTML includes:
- the banner UI,
- a small consent script,
- essential site code only,
- no live analytics or ad scripts yet.
- The browser renders the page and shows a banner with clear choices such as:
- “Accept all”
- “Reject non-essential”
- “Manage preferences”
- The visitor clicks “Manage preferences” and enables “Analytics” but leaves “Advertising” off.
- The site stores that choice in a consent cookie or local storage entry. The stored record should include the categories chosen and when the choice was made.
- The tag loader reads the stored choice.
- The tag loader now loads Google Analytics because the visitor allowed analytics.
- The tag loader does not load the Meta pixel because advertising was refused.
- The YouTube embed stays blocked behind a placeholder until the visitor separately allows the relevant category, if that embed sets non-essential identifiers.
- On the next page view, the site reads the stored consent first and applies the same rules immediately.
- The visitor can later reopen preferences and withdraw consent. After withdrawal, the site must stop loading those optional tools on future page loads, and where practical, trigger vendor-specific consent update APIs.
That is the core mechanism: default deny for non-essential processing, then selective activation after a real choice.
What counts as “must do” in practice
A cookie banner generally needs to do all of these to stay on the right side of common privacy expectations under laws like the ePrivacy rules and consent standards used with GDPR:
- Block non-essential cookies and trackers before consent. If analytics fires before the click, the banner is already failing.
- Offer a real reject option on the first layer. Hiding refusal behind extra clicks is a common problem.
- Use clear language. “We value your privacy” is not enough; say what categories exist and what they do.
- Separate categories where relevant. For example: necessary, analytics, advertising, functional.
- Record the choice. You need evidence of what was selected and when.
- Honor the choice. Do not reload blocked tools on the next page or through another script path.
- Allow withdrawal later. Usually via a persistent “Privacy settings” or “Cookie settings” link in the footer.
- Keep necessary cookies separate. Strictly necessary items should not be bundled into “accept all.”
When to use it (and when not to)
If your site uses anything beyond strictly necessary cookies or equivalent tracking, you probably need a real consent mechanism, not just a notice.
| Scenario | Recommendation |
|---|---|
| Brochure site with analytics, ad pixels, chat widget, video embeds | Use a full consent banner with category-based blocking |
| Ecommerce site with cart/session cookies plus analytics | Use a banner; cart/session can stay active as necessary, analytics must wait for consent |
| Internal tool behind company login, no marketing tags, only security/session cookies | You may not need a marketing-style banner; document the necessary cookies instead |
| Public site using only strictly necessary cookies for login, load balancing, or fraud prevention | You probably do not need an opt-in banner for those cookies alone, but you still need clear disclosure |
| Site using server-side analytics that do not rely on browser identifiers and are configured for low privacy impact | Get legal review; you may reduce banner scope, but do not assume exemption automatically |
| Site with embedded third-party content like maps, videos, social widgets | Use a banner or prior-blocking placeholders, because embeds often set identifiers before interaction |
You probably do not need a full cookie banner if all of the following are true:
- your site sets only strictly necessary cookies,
- you do not run analytics, ads, personalization, chat, replay, or social embeds,
- you are not reading browser identifiers for optional purposes.
Many businesses think “we only use Google Analytics” means the banner can be lightweight. In practice, analytics is usually exactly why consent is needed.
Trade-offs
Every privacy control has a business cost. It is better to understand that upfront.
-
Benefit: lower legal and reputational risk
Cost: less data, especially fewer marketing and analytics events because some visitors will refuse. -
Benefit: clearer user choice and better trust
Cost: more UI work. You need banner copy, preferences screens, and a way to reopen settings. -
Benefit: cleaner data governance
Cost: implementation complexity. You must map every script and cookie to a category and keep that inventory current. -
Benefit: easier audits
Cost: operational burden. New plugins, embeds, and marketing tools must be reviewed before launch. -
Benefit: better control over third-party tags
Cost: possible vendor lock-in if you use a consent platform deeply tied to one tag manager or analytics stack. -
Benefit: reduced accidental tracking
Cost: performance and engineering effort. Some tools need conditional loading logic, placeholders, or consent-mode integration.
The biggest hidden cost is maintenance. A banner can be compliant on launch day and non-compliant six months later because someone added a heatmap script directly into the site template.
In practice
Below are two practical patterns you can adapt.
Example 1: Block analytics until consent in plain HTML/JavaScript
This example shows the core idea without any vendor-specific product. It stores a simple consent state and only injects analytics after the user accepts that category.
<script>
function getConsent() {
try {
return JSON.parse(localStorage.getItem('consent') || '{}');
} catch (e) {
return {};
}
}
function setConsent(consent) {
localStorage.setItem('consent', JSON.stringify(consent));
}
function loadAnalytics() {
if (window.analyticsLoaded) return;
window.analyticsLoaded = true;
var s = document.createElement('script');
s.src = 'https://analytics.example-vendor.com/script.js';
s.async = true;
document.head.appendChild(s);
}
document.addEventListener('DOMContentLoaded', function () {
var consent = getConsent();
if (consent.analytics === true) {
loadAnalytics();
}
document.getElementById('accept-all').addEventListener('click', function () {
setConsent({ necessary: true, analytics: true, advertising: true, ts: Date.now() });
loadAnalytics();
document.getElementById('cookie-banner').hidden = true;
});
document.getElementById('reject-all').addEventListener('click', function () {
setConsent({ necessary: true, analytics: false, advertising: false, ts: Date.now() });
document.getElementById('cookie-banner').hidden = true;
});
});
</script>
What it does: keeps analytics off by default and turns it on only after consent. Gotcha: this only works if you also remove any analytics code already hardcoded elsewhere in the page, tag manager, CMS theme, or plugin.
Example 2: Gate a tag in Google Tag Manager-style data layer logic
If your agency or marketing team uses a tag manager, the practical job is to push consent state first and trigger tags only when the category is granted.
<script>
window.dataLayer = window.dataLayer || [];
function pushConsentState() {
var consent = JSON.parse(localStorage.getItem('consent') || '{}');
window.dataLayer.push({
event: 'consent_update',
consent_analytics: consent.analytics === true ? 'granted' : 'denied',
consent_advertising: consent.advertising === true ? 'granted' : 'denied'
});
}
document.addEventListener('DOMContentLoaded', pushConsentState);
</script>
What it does: sends consent status into the tag manager so tags can be configured to fire only when allowed. Gotcha: a tag manager does not magically make you compliant; if the container itself or custom HTML tags load trackers before consent rules apply, you still have a problem.
Practical implementation checklist
In your CMS, hosting dashboard, or tag manager workspace, walk through these actions:
- Open your site template or tag manager and list every script that loads on every page.
- Put each one into a category: necessary, analytics, advertising, functional, or unknown.
- Remove optional scripts from the default page template.
- Add them back only through consent-aware loading rules.
- Add a footer link named “Cookie settings” or “Privacy settings” that reopens the preference panel.
- Test in a private/incognito browser window.
- In the browser’s developer tools, open Application/Storage → Cookies and Network:
- load the page without interacting,
- confirm optional vendor requests do not appear,
- click accept for one category,
- confirm only that category’s vendors now load.
⚠️ If you use a CMS plugin, theme, or app marketplace extension, disabling a script in one place may break reporting or marketing campaigns. Change one integration at a time and test in staging first if you have it.
Further reading
- European Data Protection Board Guidelines 05/2020 on consent under Regulation 2016/679
- CNIL guidance on cookies and other trackers
- ICO guidance on cookies and similar technologies
- The "Using HTTP cookies" article in the MDN Web Docs HTTP section
- Google Tag Manager Help: consent mode and consent settings
This article was written by an AI system and published pending human review. Verify anything you intend to act on.
Have a project in mind?
Get an instant AI price estimate for it, or talk directly to our team.
One email a month on what we learn building with AI