How to Add a Cookie Consent Banner to an AI-Built App
Ask an AI app builder for a cookie consent banner and you will get one in about ten seconds. It will look right. It will have Accept and Reject buttons, a tidy explanation, and a preference saved to local storage.
How to Add a Cookie Consent Banner to an AI-Built App
Ask an AI app builder for a cookie consent banner and you will get one in about ten seconds. It will look right. It will have Accept and Reject buttons, a tidy explanation, and a preference saved to local storage.
It will also, in most cases, be legally useless, because the analytics script loaded before anyone clicked anything. The banner records a choice it does not enforce.
This is worth understanding rather than delegating, because it is one of the few areas where a plausible-looking implementation and a correct one are visually identical and only one of them protects you.
The rule the banner has to satisfy
Under the EU ePrivacy rules and GDPR's consent standard, and similar regimes elsewhere such as the UK ICO's cookie guidance, the requirement is roughly this: before you store or read anything on a user's device that is not strictly necessary to deliver the service they asked for, you need their consent.
The load-bearing words are before and strictly necessary.
"Before" means the consent decision has to gate the script, not follow it. A banner that appears while Google Analytics is already reporting a pageview has not obtained consent for that pageview. This is the failure mode that generated banners land in almost every time.
"Strictly necessary" is narrower than most people assume. It covers what breaks the site if removed, not what is important to your business.
Cookie or storage | Consent needed? | Why |
|---|---|---|
Session token / login state | No | Strictly necessary for a service the user requested |
CSRF token | No | Security, strictly necessary |
Load balancer / routing | No | Necessary for delivery |
Shopping cart contents | No | The user asked for the cart |
Language or theme set by the user | No | Explicit user preference |
Analytics, including self-hosted | Yes | Not necessary to deliver the service |
A/B testing | Yes | Not necessary |
Advertising and retargeting pixels | Yes | Not necessary, and higher scrutiny |
Session replay / heatmaps | Yes | Not necessary, and captures user content |
Embedded video that sets cookies | Yes | Third party storage on your page |
Two things that trip people up: analytics is not exempt just because you self-host it, and this applies to local storage and similar client-side storage, not only to things technically named cookies.
What a generated banner usually gets wrong
Four recurring problems, in the order they matter.
1. Scripts load before consent. The tracking snippet sits in the page head, or in a component that mounts on load, and runs independent of banner state. The banner then writes `consent=true` to local storage and nothing downstream reads it.
2. Reject is harder than Accept. A prominent Accept button and a "Manage preferences" link leading to a settings panel with a toggle is not equivalent effort. Rejecting all non-essential storage needs to be available in one click, at the same level as accepting.
3. Pre-ticked boxes, or no real choice. Categories toggled on by default, or a banner with only a dismiss control, do not produce valid consent. Silence and inaction are not agreement.
4. No way to change your mind. Consent has to be as withdrawable as it was givable. If the banner disappears forever after the first click with no route back, there is no withdrawal mechanism.
Building it properly
The architectural point is small and everything follows from it: consent state must be the gate that loads third-party code, not a value written alongside it.
Step 1: inventory what you actually set
Open your app in a private window, open developer tools, and look at Application, then Cookies and Local Storage, before touching anything. Everything present at that moment loaded without consent. Write the list down. It is usually longer than expected, because AI app builders add analytics and error monitoring helpfully and quietly.
Step 2: default to denied
Consent state has three values, not two: unknown, granted, denied. Unknown behaves exactly like denied. The only difference is that unknown shows the banner.
// consent.js
const KEY = 'consent.v1'
export function getConsent() {
try {
return JSON.parse(localStorage.getItem(KEY)) ?? { analytics: false, marketing: false, decided: false }
} catch {
return { analytics: false, marketing: false, decided: false }
}
}
export function setConsent(next) {
localStorage.setItem(KEY, JSON.stringify({ ...next, decided: true }))
window.dispatchEvent(new CustomEvent('consentchange', { detail: next }))
}Storing the consent record itself is strictly necessary, so it does not need consent.
Step 3: load scripts only after a grant
Remove every non-essential script tag from your HTML. Load them from code, on the consent event.
// analytics.js
let loaded = false
function loadAnalytics() {
if (loaded) return
loaded = true
const s = document.createElement('script')
s.src = 'https://example-analytics.test/script.js'
s.async = true
document.head.appendChild(s)
}
function apply(consent) {
if (consent.analytics) loadAnalytics()
}
apply(getConsent())
window.addEventListener('consentchange', (e) => apply(e.detail))Note what this does not do: it never unloads anything. Revoking consent in a live tab cannot reliably unring that bell, so revocation should also clear the relevant cookies and reload the page.
Step 4: give equal weight to both answers
Accept and Reject as two buttons, same size, same prominence, same click count. A third link to granular settings is fine and often good, but it cannot be the only route to rejection.
Step 5: leave a way back
A persistent "Cookie settings" link in the footer that reopens the banner. One line of code, and it is the difference between a compliant implementation and one that collects consent it cannot honour a change to.
Step 6: verify by testing, not by reading
Private window, developer tools open, load the app, and click nothing.
Cookies and local storage should contain only your consent record and genuinely necessary items.
The network tab should show no requests to analytics or advertising domains.
Click Reject: still nothing.
Click Accept: now the requests appear.
If anything fires before the click, the banner is decorative. This test takes two minutes and is the only check that matters.
Getting the AI builder to do it right
The prompt shape that works is one that specifies the gating behaviour rather than the artifact:
Add a cookie consent banner. Do not load any analytics or third-party scripts until consent is granted. Consent state lives in a module other code subscribes to, defaults to denied, and all non-essential script tags are removed from the HTML and loaded dynamically after a grant. Accept and Reject must be equally prominent single-click actions, and a footer link must reopen the banner.
Then verify with the private-window test yourself. This is a good example of a task where the model will produce confident, well-structured, wrong code if you ask for the visible thing instead of the behaviour, which is the general lesson in why AI writes code that does not work.
Where this fits with everything else
A consent banner is one piece of a privacy posture, not the whole of it. The neighbouring pieces:
Adding GDPR data deletion to an AI-built app, which is the request people actually send you.
Writing a privacy policy for an AI app, which needs to match what the banner does.
Adding analytics in the first place, where the choice of tool affects how much consent you need.
How to build an app with AI for the broader build process this sits inside.
One honest caveat: this is a summary of how the rules work in practice, not legal advice. Requirements vary by jurisdiction, and if you are operating at scale or in a regulated sector, have a lawyer look at your specific setup. The engineering point stands regardless of jurisdiction: a consent decision that does not gate the code is not a consent mechanism.
FAQ
Do I need a cookie banner if I only use essential cookies? No consent banner is required for strictly necessary cookies, though you should still describe them in your privacy policy. The catch is that analytics is not strictly necessary, so most apps that think they qualify do not.
Does local storage count, or only cookies? It counts. The rules cover storing and accessing information on a user's device, which includes local storage, session storage and IndexedDB. The common name for the law is misleading.
Can I just use a third-party consent management platform? Yes, and for anything with advertising it is usually the sensible choice. You still have to wire your scripts to its consent signal. Installing the platform while leaving your analytics tag in the page head reproduces the original problem with extra steps.
Is Reject All actually required to be one click? Regulators across several EU jurisdictions have consistently found that making rejection meaningfully harder than acceptance invalidates consent, consistent with the EDPB's consent guidelines. One click for each is the safe implementation and the one to build.
What about users outside the EU? Scope varies, and several other jurisdictions have adopted broadly similar consent expectations. Since the correct implementation costs no more than the incorrect one, applying it everywhere is simpler than geo-gating your compliance.
How did this land?
About the author

Developer Advocate
Steve builds something with Swarmz every week and writes up what worked, what broke, and what he'd do differently. Tutorials and hands-on guides are his lane.


