The banner is not the compliance program.
A modal that screams “Accept all” while analytics fire on first paint is theater. Under the ePrivacy Directive tradition and GDPR-style consent expectations, non-essential cookies generally need consent before they are set, with plain information about purpose. Strictly necessary cookies are the usual exception — not “everything marketing wants this quarter.”
Guidance such as the ICO cookies guidance stresses specific, informed consent — not a buried policy link as the only notice. Build the banner as a small product with states, storage, and engineering hooks.

Consent is a seal. Do not open the jar before the seal is given.
Essential by default
On first visit:
- Load only what the site needs to function (security, load balancing, load balancing affinity, explicit user prefs that cannot work otherwise).
- Show a clear choice: accept analytics / essential only (or granular categories if you truly need them and can explain them).
- Do not load GA, ads, heatmaps, or personalization pixels until the stored decision allows it.
- Remember the decision; offer a way to change it later in the footer or privacy center.
If “Reject” is smaller, greyer, or harder to find than “Accept,” you are optimizing consent conversion, not trust.
Categories that match reality
Keep the model small enough that humans can understand it:
- Essential — always on; listed honestly in the policy
- Analytics — measurement not required to deliver the page
- Marketing — ads, retargeting, social pixels
Six nested categories that all default to on are a dark pattern with extra clicks.
Engineering hooks that make policy real
- Gate every non-essential script behind the stored preference
- Re-read preference on full navigations and on SPA soft navigations if you use them
- Maintain a tag inventory: script → category → owner → purpose
- Test with a clean browser profile: no calls to analytics hosts before accept
- Fail closed if preference storage is broken (no silent “assume yes”)
Consent UI without tag discipline is a sticker on a leaky pipe.
Copy that is specific
“We use cookies to improve experience” is not specific. Name classes of tools: analytics to understand traffic, marketing to measure campaigns. Link the full policy. State how long the choice is stored.
Legal partnership
Jurisdiction and cookie types interact (storage/access rules vs lawful bases for personal data). Do not invent policy from a studio blog — including this one. Bring counsel for your markets. Engineering’s job is to make the agreed policy enforceable in code and testable in QA.
Ship checklist
- Essential-only first paint verified in network panel
- Accept / reject both reachable by keyboard
- Preference change stops or starts tags without full reinstall theater
- Tag inventory reviewed this quarter
- No pre-ticked marketing boxes
Closing
Ship a banner that can say no, a default that stays essential, and tags that obey. Anything louder is usually compensating for scripts that should not have loaded yet.
Need consent wiring that matches a real tag inventory? Start a project inquiry with your current scripts list and markets you care about.
Tag inventory example
| Tag | Category | Owner | Loads when |
|---|---|---|---|
| session cookie | Essential | Eng | Always |
| GA4 | Analytics | Marketing | analytics accepted |
| ad pixel | Marketing | Marketing | marketing accepted |
Review this table quarterly. Orphan tags are how banners lose credibility.
QA script
- Clean profile, open homepage, confirm analytics host has zero requests.
- Accept analytics; confirm requests start.
- Switch to essential-only; confirm analytics stops on next page load.
- Keyboard through the banner without a pointer.
- Repeat on mobile viewport.
Regional nuance
Some markets treat analytics more strictly than others. Product and legal should name the strictest rule you will implement in code if you ship one global banner. Split banners by region only when you will maintain the matrix.