Skip to content

Best practicesPart of: Cookie consent

Cookie banner requirements: what a compliant banner needs, with examples

A cookie banner asks visitors for permission before a site sets analytics or advertising cookies. What EU and UK rules require from it, examples that pass and fail, and how to build and test one.

getReport teamUpdated 27 Sept 202616 min read

A cookie banner is the notice a website shows on a visitor's first page view to ask permission before it sets analytics, advertising or other non-essential cookies. To meet EU and UK rules it has to block those cookies until the visitor answers, put "Reject all" on the first layer as prominently as "Accept all", start with every optional box unticked, name the purposes in plain words, and let visitors change their mind later. This guide covers each requirement, shows banner examples that pass and fail, and walks through building and testing one. It is part of our guide to cookie consent and what the law requires, which explains the legal background in full.

Watch out

This guide explains the rules in plain language and names its sources, current as of September 2026. It is not legal advice. Regulators in different countries read the rules differently, and what you need depends on what your site does with data; for a decision with legal consequences, ask a qualified lawyer or your data protection officer.

Quick answer

  • You need a cookie banner when your site sets cookies or loads trackers that are not strictly necessary and has visitors in the EU or UK. Session, cart, security and consent cookies alone do not need one.
  • First layer: Reject all and Accept all, same size and weight, plus a link to per-purpose settings and to your cookie or privacy policy.
  • Every optional category starts off. Closing the banner, scrolling or carrying on browsing is not consent.
  • Nothing optional loads before the click: the banner is only as good as the tag blocking behind it.
  • A Cookie settings link on every page reopens the banner, so withdrawing is as easy as agreeing.
  • Keep consent-based cookies, including the one that stores the answer, to 13 months or less.

A cookie banner (or consent banner) is the dialog or bar that asks visitors whether the site may use optional cookies and similar identifiers. Behind it, a consent platform records the answer and switches tags on or off to match.

You need one because of Article 5(3) of the EU ePrivacy Directive and the national laws that implement it, such as PECR in the UK: storing or reading anything on a visitor's device needs prior consent unless it is strictly necessary for the service the visitor asked for. Analytics, advertising pixels, session recording and most social embeds are not strictly necessary, so they need a yes first. The guide to strictly necessary cookies lists what may load before the click.

Three cases where the answer differs:

  • Only necessary cookies: a site with a login session, a cart and nothing else needs no banner, only a mention in the privacy policy.
  • UK statistics and appearance cookies: since 5 February 2026, the Data (Use and Access) Act 2025 lets UK sites set first-party cookies used only for statistics about the service, or only to remember appearance preferences, without consent, provided visitors are told and get a simple, free way to object. Advertising still needs consent. The ICO's guidance on storage and access technologies is the reference.
  • US visitors: California's CCPA/CPRA is an opt-out model with no general consent requirement for cookies. The CCPA cookie banner guide covers "Do Not Sell or Share" and Global Privacy Control.
RequirementWhat it looks likeWhere it comes from
Prior consentNo optional tag runs until the visitor choosesePrivacy Directive Art. 5(3)
Active choiceA click on a button; no pre-ticked boxes, no "by continuing to browse you agree"GDPR Art. 4(11) and Recital 32; CJEU Planet49 (C-673/17, 2019)
Refusing as easy as accepting"Reject all" on the first layer, same size and colour weight as "Accept all"EDPB cookie banner taskforce report (January 2023); CNIL decisions
Specific and informedPurposes named (statistics, marketing), vendors and lifetimes listed on a second layerGDPR Art. 4(11) and 7; Planet49 on duration and third-party access
Easy withdrawalA link or icon on every page reopens the choiceGDPR Art. 7(3)
No deceptive designNo bright Accept next to a grey text-link Reject, no pre-enabled "legitimate interest" togglesEDPB cookie banner taskforce report (deceptive button colours and contrast)
ProofA record of who agreed to what, and whenGDPR Art. 7(1)
Proportionate lifetimeAsk again after 13 months at the mostCNIL guidance and common practice (below)

Refusal. In the EDPB's taskforce report, most EU data protection authorities treat a first layer with "Accept" but no way to refuse as a breach. The French CNIL fined Google €150 million and Facebook €60 million in January 2022 because refusing took more clicks than accepting, and in September 2025 it fined Shein €150 million for advertising cookies set as soon as visitors arrived and for incomplete cookie interfaces.

Lifetime. The CNIL caps the lifetime of consent-exempt audience-measurement cookies at 13 months and recommends remembering a visitor's answer, accept or reject, for about six months before asking again. Thirteen months is the ceiling most consent platforms and getReport's lifetime check apply to every cookie. Google Analytics' _ga lasts two years by default.

Note

The EU is revising these rules. The European Commission's Digital Omnibus proposal of November 2025 would move the cookie rules into the GDPR, require a single-click way to refuse and make browser-level consent signals binding. As of September 2026 it is still a proposal in the legislative process; until it is in force, the rules above apply.

Most banners fall into one of six patterns. The first two pass a regulator's first look; the rest are the ones complaints and fines are about.

ExampleFirst layerVerdict
Equal buttons"Accept all", "Reject all" and "Settings", the two main buttons identical in size and colourPasses
Necessary only"Accept all" and "Only necessary", same style, with settings behind a linkPasses
Accept and settings"Accept all" plus "Manage options"; refusing takes two or more clicksFails the equal-choice test
Accept and ×"Accept all" and a close icon; closing sets nothing but offers no refusal eitherFails: closing is not refusing
Grey reject linkA bright "Accept" button next to "Reject" as small grey textDeceptive design; several authorities object
Cookie wallThe page is blocked until the visitor acceptsRarely valid in the EU; see cookie walls

A good second layer lists categories (necessary, statistics, marketing) with a toggle each, all off except necessary, and a "Save choices" button. Vendors, cookies and lifetimes belong in your cookie policy, linked from the banner.

How getReport checks your banner

The scanner loads the page in a fresh Chromium session, records every cookie and tracker request, finds the banner's accept button, clicks it, waits about 2.5 seconds and records what changed. Four findings are about the banner:

The cookies table of the scanner on a fixture whose banner has no reject option: three first-party cookies, cookie_notice_accepted as necessary consent for 12 months, and _ga and _gcl_au as Google Analytics analytics cookies for 13 and 3 months, all set after accept, each with SameSite=Lax
Each cookie with its category, whether it appeared before or after the accept click, its lifetime and its flags.

In that example the tags wait for the click (every cookie says "after accept") and the lifetimes stay within 13 months. What fails is the banner itself: it offers no way to say no.

A warning, shown only when a banner was detected. The scanner looks for a visible reject control through the known selectors of 18 consent platforms, then for any visible button or link labelled with a reject phrase in about 20 languages ("Reject all", "Only necessary", "Alle ablehnen", "Tout refuser"). A reject button hidden behind "Settings" does not count. When neither an accept nor a reject control can be identified, the finding is informational only.

The finding that matters most: tags that fire before the click. Google's cookieless Consent Mode pings are not counted.

Informational. It lists every cookie the scan saw that lives longer than 397 days. Chrome caps lifetimes at 400 days, so a two-year cookie shows as 400 days and is still listed.

Informational, and only shown when the page runs an analytics or marketing tag. It passes when the page sets a Google Consent Mode default or update. For cookieless analytics such as Plausible, Consent Mode is irrelevant; ignore it there.

Build a compliant banner, step by step

1. Take the inventory

Run the scanner on the home page and one page per template (a product, an article, the contact page). List every cookie and tracker with its owner and category; that list decides the banner's categories, the blocking rules and your cookie policy. If it shows only necessary cookies, you may not need a banner at all.

TypeExamplesGood for
Open source, self-hostedKlaro, tarteaucitron.js, CookieConsent (MIT licence)Developers who want no third-party script and full control
Hosted platformsCookiebot, Usercentrics, CookieYes, iubenda, OneTrustSites that want scanning, policy text and consent logs handled; several have a free plan for small sites with limits on pages or visits
WordPress pluginsComplianz, CookieYes, Cookie NoticeWordPress sites; see choosing a WordPress cookie consent plugin

Whatever you choose, check four settings first: a first-layer reject button, Consent Mode v2 support, script blocking by category, and the lifetime of the consent cookie.

3. Design the first layer

  • Two equal buttons, "Accept all" and "Reject all", with the same class. Different colours are fine if neither one fades into the background.
  • One or two sentences naming the purposes ("analytics to count visits, marketing to measure ads") and linking to the cookie or privacy policy.
  • A "Settings" link to per-purpose toggles, all off by default.
  • No cookie wall: the page stays readable while the banner is open.

A minimal banner of your own, for a site whose only tags are Google's:

HTML
<!-- 1. First script in <head>, above gtag.js or Google Tag Manager -->
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('consent', 'default', {
    ad_storage: 'denied', ad_user_data: 'denied',
    ad_personalization: 'denied', analytics_storage: 'denied',
    wait_for_update: 500
  });
  if (/(?:^|; )site_consent=granted/.test(document.cookie)) {
    gtag('consent', 'update', {
      ad_storage: 'granted', ad_user_data: 'granted',
      ad_personalization: 'granted', analytics_storage: 'granted'
    });
  }
</script>
HTML
<!-- 2. End of <body>: the banner, hidden once a choice exists -->
<div id="consent-banner" role="region" aria-label="Cookie consent" hidden>
  <p>We use analytics and marketing cookies only if you agree.
     <a href="/privacy-policy/#cookies">What we use</a></p>
  <button type="button" class="consent-btn" id="consent-reject">Reject all</button>
  <button type="button" class="consent-btn" id="consent-accept">Accept all</button>
</div>
<script>
  (function () {
    var banner = document.getElementById('consent-banner');
    if (!/(?:^|; )site_consent=/.test(document.cookie)) banner.hidden = false;
    function choose(granted) {
      var v = granted ? 'granted' : 'denied';
      gtag('consent', 'update', {
        ad_storage: v, ad_user_data: v, ad_personalization: v, analytics_storage: v
      });
      // 180 days, well inside the 13-month limit
      document.cookie = 'site_consent=' + v + '; Max-Age=15552000; Path=/; SameSite=Lax; Secure';
      banner.hidden = true;
    }
    document.getElementById('consent-accept').addEventListener('click', function () { choose(true); });
    document.getElementById('consent-reject').addEventListener('click', function () { choose(false); });
  })();
</script>

A footer link that deletes site_consent and shows the banner again gives visitors their way back. This covers Google's tags only; any other tracker must load after "Accept", which is what consent platforms automate. The Google Consent Mode v2 guide explains basic and advanced mode.

4. Block everything else by category

Non-Google tags ignore Consent Mode. In Tag Manager, require consent in each tag's Consent Settings or fire it on your platform's consent event; in the page's HTML, use the platform's type="text/plain" pattern with a category attribute. The strictly necessary cookies guide has the code for Cookiebot and OneTrust.

5. Set lifetimes

Shorten Google Analytics in GA4 (Admin → Data streams → your stream → Configure tag settings → Override cookie settings) or in the tag:

JavaScript
// gtag.js config (in Tag Manager: the Google tag's cookie_expires parameter), value in seconds
gtag('config', 'G-XXXXXXXXXX', { cookie_expires: 395 * 24 * 60 * 60 });

In your consent platform, set the consent cookie to 6 to 12 months.

6. Test before the click and after reject

Run the scanner again: no trackers before consent, the reject finding names your button, no cookie over 13 months. Then test "Reject" by hand, because the scanner only clicks accept: a new private window, DevTools open, click "Reject all", reload, open a second page. No _ga, _fbp or similar cookies should appear, and no tracker requests beyond Google's cookieless pings.

  • One consent platform, not two. Each is a script that has to run before your tags.
  • Overlay, don't push. A fixed overlay at the bottom of the screen does not move the page; a banner inserted at the top of the document pushes everything down and counts as layout shift. Fix Cumulative Layout Shift covers the rest.
  • Keep the text short. On phones the banner text is often the largest element on screen and can become the page's Largest Contentful Paint.
  • Make it accessible. Real <button> elements, visible focus, reachable by keyboard, readable at 200 % zoom.

Platform notes

  • WordPress: Complianz, CookieYes and Cookie Notice all have a first-layer reject setting; check it is on. Plugins that print their own tags need a consent integration, or they fire regardless of the banner.
  • Shopify: the built-in banner (Settings → Customer privacy) offers accept and decline. Pixels added under Settings → Customer events follow the choice; code pasted into the theme does not.
  • Static sites and custom builds: consent defaults first, then the consent platform, then Tag Manager, with every other tag inside Tag Manager.

Common mistakes

  • Accept and an ×, nothing else. Closing the banner is not refusing, and the scanner does not treat an × as a reject control.
  • A pixel hard-coded in the theme. The banner is configured, but a copy of the tag outside the consent platform fires anyway. The trackers finding names it.
  • A banner the scan cannot see. Banners inside an iframe or hidden from headless browsers leave the scan with the before-consent state only; check the reject button by hand.

Questions people ask

Cookie banners are the pop-ups or bars that ask whether a website may use optional cookies, such as analytics and advertising. Sites show them because EU and UK law requires consent before storing or reading non-essential information on your device. A compliant banner lets you accept or reject with one click each, blocks tracking until you choose, and lets you change your answer later through a "Cookie settings" link.

In the EU, in practice yes. France's CNIL has fined large sites where refusing cookies took more clicks than accepting them, and the EDPB's cookie banner taskforce agreed that offering Accept without a way to refuse on the same layer does not meet the rules. Put Reject all next to Accept all on the first layer, with the same size and prominence, so refusing is as easy as accepting.

Under the GDPR and the ePrivacy rules, a cookie banner must ask before any non-essential cookie or tracker loads, offer rejecting as easily as accepting (a "Reject all" next to "Accept all" on the first layer), explain the purposes in plain language, use no pre-ticked boxes, let visitors change their mind later, and keep proof of consent. Consent should also be renewed periodically; 13 months is the common ceiling.

No. Consent under the GDPR needs a clear affirmative action, and closing a dialog is not one. It is not a clear refusal either, so a site that treats × as "accept" breaks the rules, and one that offers only Accept and × fails the equal-choice test. Treat a closed banner as no consent given and ask again on the next page, or better, add a "Reject all" button.

How do I check which cookies my website sets?

Run a cookie scanner: it loads the page in a fresh browser, lists every cookie and tracker before and after accepting the banner, with category, lifetime and flags, and flags trackers that load before consent. To check by hand, open a private window, then the browser's developer tools → Application → Cookies, and load the page without clicking the banner. Repeat on a product, article and contact page.

Ask again after 13 months at the most. That is the ceiling most consent platforms and getReport's lifetime check use, based on the French CNIL's guidance, which also recommends remembering a choice, including a refusal, for about six months. It applies to the cookie that stores the visitor's answer too. Google Analytics' _ga cookie lasts two years by default, so shorten it in the tag settings.

Check your site before and after Check