Cookie Consent Banner

Generates a working consent banner - blocks tagged scripts until consent, Google Consent Mode v2, no dark patterns.

100% free. Runs entirely in your browser - your files and data never leave your device and nothing is uploaded to any server.

Template, not legal advice. This generates working code, not legal advice. It gives you a compliant mechanism; whether your site is compliant also depends on what you connect to it. Two things it cannot do for you: tag every third-party script so the blocker can hold it back, and keep a record of consents if your regulator expects one. Test it with your browser developer tools open - if a tracking cookie appears before you click Accept, something is still loading outside the blocker.

Start from an example

Fills every answer with a worked example you can edit. Pick the one closest to your business.

0 of 3 details filled
Your site
Which consent model

Opt-in is required in the UK and EU. If you have any European visitors at all, choose it.

Opt-in is required in the UK and EU. If you have any European visitors at all, choose it.
Appearance
Recommended. A single Accept-or-Reject is legal but converts worse than letting people keep analytics on and turn advertising off.
Signals and behaviour
Needed if you use Google Analytics or Google Ads and have EEA or UK visitors. Without it Google stops modelling data for those users.
Required in California and several other US states. The browser sends it automatically; this treats it as a rejection.
Consent has to be as easy to withdraw as it was to give, so there must be a way back to this after the banner is gone.

Cookie Consent Banner

5 sections · 1111 words · updates as you type

Cookie Consent Banner

Last updated: 13 September 2026

Paste this into your site

<!-- Cookie consent banner. Put the <style> and <script> in <head>,
     and the markup just before </body>. -->
<style>
#cc-banner{position:fixed;z-index:2147483000;right:16px;bottom:16px;max-width:420px;width:calc(100% - 32px);
  box-sizing:border-box;padding:20px;background:#fff;color:#0f172a;border:1px solid #e2e8f0;
  border-radius:14px;box-shadow:0 10px 40px rgba(2,6,23,.18);
  font:15px/1.55 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif}
#cc-banner h2{margin:0 0 8px;font-size:1rem;font-weight:650}
#cc-banner p{margin:0 0 14px;color:#475569}
#cc-banner a{color:#4f46e5;text-decoration:underline}
#cc-actions{display:flex;gap:10px;flex-wrap:wrap}
#cc-banner button{flex:1 1 auto;min-width:120px;padding:11px 16px;border-radius:9px;
  font:inherit;font-weight:600;cursor:pointer;border:1px solid #4f46e5}
#cc-accept{background:#4f46e5;color:#fff}
#cc-reject{background:transparent;color:#4f46e5}
#cc-prefs{flex:0 0 auto;min-width:0;background:transparent;color:#475569;border-color:transparent;text-decoration:underline}
#cc-banner button:focus-visible{outline:3px solid #4f46e5;outline-offset:2px}
#cc-options{display:none;margin:0 0 14px;padding:12px 0 0;border-top:1px solid #e2e8f0}
#cc-options.cc-open{display:block}
#cc-options label{display:flex;gap:10px;align-items:flex-start;margin:0 0 10px;cursor:pointer}
#cc-options input{margin-top:3px;width:18px;height:18px;accent-color:#4f46e5}
#cc-options small{display:block;color:#64748b}
#cc-reopen{background:none;border:0;padding:0;font:inherit;color:inherit;text-decoration:underline;cursor:pointer}
@media (prefers-color-scheme:dark){
  #cc-banner{background:#0f172a;color:#e2e8f0;border-color:#1e293b}
  #cc-banner p{color:#94a3b8}
  #cc-prefs{color:#94a3b8}
  #cc-options{border-top-color:#1e293b}#cc-options small{color:#94a3b8}
}
@media (prefers-reduced-motion:reduce){#cc-banner{transition:none}}
</style>

<div id="cc-banner" role="dialog" aria-modal="false" aria-labelledby="cc-title" aria-describedby="cc-desc" hidden>
  <h2 id="cc-title">Cookies on this site</h2>
  <p id="cc-desc">We use cookies to run this site and, with your permission, to understand how it is used.
    Nothing optional is set until you choose.
    <a href="/cookie-policy">Read our cookie policy</a>.</p>
  <div id="cc-options">
    <label><input type="checkbox" checked disabled>
      <span>Essential<small>Needed for the site to work. Always on.</small></span></label>
    <label><input type="checkbox" id="cc-analytics">
      <span>Analytics<small>Counts visits so we can see what is used.</small></span></label>
    <label><input type="checkbox" id="cc-marketing">
      <span>Marketing<small>Measures advertising and allows targeted ads.</small></span></label>
  </div>
  <div id="cc-actions">
    <button type="button" id="cc-accept">Accept all</button>
    <button type="button" id="cc-reject">Reject all</button>
    <button type="button" id="cc-prefs">Choose</button>
  </div>
</div>

<script>
(function () {
  var KEY = "cc-consent-v1";
  var el = function (id) { return document.getElementById(id); };
  var banner = el("cc-banner");

  function read() {
    try { return JSON.parse(localStorage.getItem(KEY) || "null"); } catch (e) { return null; }
  }
  function write(state) {
    try { localStorage.setItem(KEY, JSON.stringify(state)); } catch (e) {}
  }

  // Google Consent Mode v2. Must run BEFORE the Google tag loads,
  // which is why this snippet goes in the head.
  window.dataLayer = window.dataLayer || [];
  function gtag() { window.dataLayer.push(arguments); }
  function signal(state) {
    gtag("consent", "update", {
      analytics_storage: state.analytics ? "granted" : "denied",
      ad_storage: state.marketing ? "granted" : "denied",
      ad_user_data: state.marketing ? "granted" : "denied",
      ad_personalization: state.marketing ? "granted" : "denied"
    });
  }
  gtag("consent", "default", {
    analytics_storage: "denied",
    ad_storage: "denied",
    ad_user_data: "denied",
    ad_personalization: "denied",
    wait_for_update: 500
  });

  // Turns every blocked script tag of a granted category into a real one.
  // Scripts are written as: <script type="text/plain" data-consent="analytics" src="...">
  function unblock(state) {
    var nodes = document.querySelectorAll("script[type='text/plain'][data-consent]");
    for (var i = 0; i < nodes.length; i++) {
      var node = nodes[i];
      var want = node.getAttribute("data-consent");
      if (!state[want]) continue;
      var live = document.createElement("script");
      for (var j = 0; j < node.attributes.length; j++) {
        var at = node.attributes[j];
        if (at.name !== "type" && at.name !== "data-consent") live.setAttribute(at.name, at.value);
      }
      live.text = node.text;
      node.parentNode.replaceChild(live, node);
    }
  }

  function apply(state) {
    write(state);
    signal(state);
    unblock(state);
    document.dispatchEvent(new CustomEvent("cc:consent", { detail: state }));
    hide();
  }

  function show() {
    banner.hidden = false;
    banner.querySelector("button").focus();
  }
  function hide() {
    banner.hidden = true;
  }

  el("cc-accept").addEventListener("click", function () {
    apply({ essential: true, analytics: true, marketing: true, at: Date.now() });
  });
  el("cc-reject").addEventListener("click", function () {
    apply({ essential: true, analytics: false, marketing: false, at: Date.now() });
  });
  el("cc-prefs").addEventListener("click", function () {
    var panel = el("cc-options");
    if (!panel.classList.contains("cc-open")) {
      panel.classList.add("cc-open");
      this.textContent = "Save choices";
      return;
    }
    apply({
      essential: true,
      analytics: el("cc-analytics").checked,
      marketing: el("cc-marketing").checked,
      at: Date.now()
    });
  });

  // Withdrawing consent has to be as easy as giving it, so this
  // reopens the banner from anywhere: <button id="cc-reopen">Cookie settings</button>
  var reopen = el("cc-reopen");
  if (reopen) reopen.addEventListener("click", show);

  var saved = read();
  // Global Privacy Control: a browser-level opt-out that US state law
  // requires you to honour. Treated as a rejection, recorded so the
  // banner does not then ask a question it has already answered.
  if (!saved && (navigator.globalPrivacyControl === true)) {
    apply({ essential: true, analytics: false, marketing: false, gpc: true, at: Date.now() });
    return;
  }
  if (saved) {
    signal(saved);
    unblock(saved);
    if (el("cc-analytics")) el("cc-analytics").checked = !!saved.analytics;
    if (el("cc-marketing")) el("cc-marketing").checked = !!saved.marketing;
  } else {
    show();
  }
})();
</script>

How to install it

1. Copy the block above into your page. The style and script can go in the head; the markup goes just before the closing body tag. On WordPress, a "header and footer scripts" plugin is the usual place; on Shopify it is theme.liquid.

2. Find every tracking script on your site - analytics, pixels, chat widgets, heatmaps.

3. Change each one from type="text/javascript" to type="text/plain" and add data-consent="analytics" or data-consent="marketing". That is what holds them back until someone agrees; a script you forget to tag will keep loading regardless of what the banner says.

4. Leave the Google tag itself in place and untagged. Consent Mode signals handle it: the tag loads, but it stores nothing until the consent update grants it.

5. Add a button with id="cc-reopen" to your footer, labelled something like "Cookie settings". Consent must be as easy to withdraw as it was to give, and that button is how.

6. Test it. Open a private window with developer tools on the Application tab, load the site, and look at Cookies before you click anything. If a tracker has already written one, it is not tagged properly.

What a blocked script looks like

<!-- BEFORE - runs immediately, sets cookies before anyone agrees -->
<script src="https://example-analytics.com/tag.js"></script>

<!-- AFTER - held back until consent for its category exists -->
<script type="text/plain" data-consent="analytics"
        src="https://example-analytics.com/tag.js"></script>

<!-- Inline scripts work the same way -->
<script type="text/plain" data-consent="marketing">
  /* pixel code here */
</script>

Reacting to a choice in your own code

// Fires every time a decision is made or restored on load.
document.addEventListener("cc:consent", function (e) {
  if (e.detail.analytics) {
    // start something that needs analytics consent
  }
});

// Read the stored decision anywhere:
var consent = JSON.parse(localStorage.getItem("cc-consent-v1") || "null");

What this banner does and does not do

What it does

  • Sets nothing before a choice. Tagged scripts stay inert until someone accepts, which is what the UK and EU rules require and what most free snippets get wrong.
  • Gives Reject the same weight as Accept. Same size, same prominence, one click. A greyed-out or hidden reject option is a dark pattern that has attracted fines.
  • Remembers the decision in localStorage under a versioned key, so changing the key re-asks everyone when your cookies change.
  • Works with a keyboard and a screen reader. It is a labelled dialog, focus moves into it, and the controls are real buttons.
  • Honours Global Privacy Control. Browsers that send the signal are treated as having rejected, without being asked - which is what California and several other states require.
  • Sends Google Consent Mode v2 signals , so Google Analytics and Google Ads behave correctly for EEA and UK visitors instead of silently dropping them.

What it does not do

  • It does not keep a server-side record of who consented and when. If your regulator or your DPO expects an audit trail, you need to post the decision to your own endpoint - the cc:consent event is where to do it.
  • It does not scan your site for trackers. Anything you do not tag keeps loading.
  • It does not write your cookie policy. The banner links to it; you still need the page.

Generated from a template. Not legal advice - read it before you publish or sign it.

Other documents you can generate

Most sites need more than one. A privacy policy without terms, or terms without a refund policy, leaves the obvious gap.

Privacy PolicyA privacy policy written from what your site actually does - GDPR and CCPA sections included only where they apply.Terms and ConditionsTerms of service built around what you actually sell - goods, subscription, downloads or services.Cookie PolicyA cookie policy with a real table - each cookie named, with its purpose and how long it lasts.Refund and Return PolicyA refund policy customers can follow and payment processors accept - windows, exclusions and statutory rights in plain words.Website DisclaimerA disclaimer that names the actual risk your site carries, plus affiliate and sponsorship disclosures.Accessibility StatementA WCAG accessibility statement that states what you actually meet, names known issues, and gives people a route to report problems.Non-Disclosure AgreementA mutual or one-way NDA with a real purpose clause, standard carve-outs and a defined term.Freelance ContractAn independent contractor agreement that pins down scope, revisions, IP ownership and what happens when payment is late.Data Processing AgreementA GDPR Article 28 processor agreement with the eight mandatory clauses and a filled-in processing schedule.W-9 FormFills a substitute Form W-9 in your browser - your TIN is never uploaded, stored or sent anywhere.1099-NEC Contractor SummaryPrepares a 1099-NEC recipient statement and a payer summary - with a straight answer about what you can and cannot print yourself.Shipping PolicyA shipping policy Shopify and Amazon sellers can publish - origin, times, tracking, duties and who pays.DSAR Form GeneratorA data-delete and access request page you can host - GDPR and CCPA wording, no upload, no signup.

About this tool

Answer a handful of questions and the banner writes itself. It exists for developers and site owners who need a working consent mechanism rather than another policy page, and the same day you add analytics or an advertising pixel, not afterwards is when it is worth twenty minutes. This is the only tool in the set that outputs code rather than prose, because a cookie policy describes what you set while a banner is the thing that stops you setting it. Most free snippets set the cookie first and show a notice second, which is the precise behaviour the ePrivacy Directive forbids. The questionnaire is not decoration. Clauses appear and disappear based on what you tell it, which is why two people using this page get materially different banners rather than the same text with a different name at the top. Everything runs in your browser. What you type is never uploaded, never stored, and gone when you close the tab - which matters here more than on most tools, because these documents carry company details, client names and sometimes tax identifiers.

How to use this tool

  1. Answer the questionsSite name. Link to your cookie policy. Which consent model do you need?. Nothing you type leaves the browser.
  2. Watch it assembleClauses appear and disappear as you answer, so the banner matches what you actually do rather than a generic template.
  3. Copy or downloadCopy the code, or download the HTML file and paste it into your site.

Key features

  • Outputs working code you can paste, not instructions to implement it yourself.
  • Built from your answers, so clauses you do not need are left out rather than padded.
  • Free with no watermark, no email wall and no per-document limit.
  • Says plainly what it is and is not, above the preview rather than in a footer.
  • Runs entirely in your browser. Nothing uploaded, nothing stored, no account.

Common uses

  • Replacing a copied banner that describes a different business.
  • Giving a lawyer a draft to review rather than paying them to start from nothing.
  • Developers and site owners who need a working consent mechanism rather than another policy page.
  • Getting something in place the same day you add analytics or an advertising pixel, not afterwards.
  • Preparing what a client, an app store or a payment processor has asked to see.

Tips for better results

  • Fill in the free-text fields rather than skipping them. The named lists - processors, exclusions, deliverables - are what make it read as yours rather than copied.
  • Installing the banner and leaving the tracking scripts untouched. The banner blocks nothing on its own - every script has to be retagged so the blocker can hold it back, and an untagged pixel keeps firing while the banner politely asks permission.
  • Test with developer tools open. If a tracking cookie appears before you click Accept, a script is still loading outside the blocker.
  • Read it before you publish it. It is a draft built from standard clauses, and you are the only person who knows whether every line is true of you.

Mistakes to avoid

  • Installing the banner and leaving the tracking scripts untouched. The banner blocks nothing on its own - every script has to be retagged so the blocker can hold it back, and an untagged pixel keeps firing while the banner politely asks permission.
  • Publishing it and never looking again. These go stale - you add a tool, change a processor, start selling somewhere new, and the banner still describes last year.
  • Treating a generated draft as a reviewed one. This is a starting point, and where the stakes are real it is worth a professional reading it.
  • Leaving the placeholder text in. Anything in square brackets is a field you skipped, and readers spot them immediately.

Frequently asked questions

Answer the questions on the left. The banner builds as you type, and you can copy it, or download it as PDF, Word or plain text when it looks right.

No. It assembles a draft from standard clauses, and every page says so above the preview. The largest EU cookie fines have not been for missing banners. They were for banners where rejecting was harder than accepting, or where trackers ran regardless of the answer.

No. Everything happens on your device - nothing is sent to a server, nothing is stored, and closing the tab clears it.

Installing the banner and leaving the tracking scripts untouched. The banner blocks nothing on its own - every script has to be retagged so the blocker can hold it back, and an untagged pixel keeps firing while the banner politely asks permission.

Yes. Download the Word version and change anything you like - it is a normal .docx with no protection on it.

Most people need Cookie Policy and Privacy Policy as well. They cover the gaps this one does not.

Broadly, developers and site owners who need a working consent mechanism rather than another policy page. The best time to do it is the same day you add analytics or an advertising pixel, not afterwards.

People also search for

  • cookie consent banner generator no signup
  • cookie consent banner generator for small business
  • cookie consent banner generator usa
  • cookie consent banner generator uk
  • free cookie consent banner generator
  • cookie consent banner generator template
  • cookie consent banner generator

Related guides