Legal Requirements for Cookie Banners under GDPR & ePrivacy
Under the ePrivacy Directive and GDPR Article 7:
- Explicit Opt-in: Non-essential cookies (Analytics, Advertising) must be blocked by default before consent is explicitly granted.
- No Pre-ticked Boxes: Users must actively tick consent checkboxes.
- Equal Prominence: Reject buttons must be as easily visible and accessible as Accept buttons.
- Consent Mode v2 Support: Required by Google for tracking signals in EEA regions.
1. Google Consent Mode v2 Script Initialization
Initialize gtag with default consent set to 'denied' before loading any analytics or ad tracking scripts:
<!-- Inline Script Placed in Head BEFORE GTM or GA4 -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
// Default state: DENIED for all non-essential signals per GDPR
gtag('consent', 'default', {
'ad_storage': 'denied',
'analytics_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'wait_for_update': 500
});
gtag('set', 'ads_data_redaction', true);
</script>
2. Vanilla JavaScript Consent Manager Engine
// CookieConsent.js - Client-Side Zero-Telemetry Consent Controller
export class CookieConsentManager {
constructor() {
this.STORAGE_KEY = 'sovereign_cookie_consent_v2';
this.init();
}
init() {
const savedState = this.getConsentState();
if (savedState) {
this.updateGoogleConsent(savedState);
} else {
this.renderBanner();
}
}
getConsentState() {
try {
const item = localStorage.getItem(this.STORAGE_KEY);
return item ? JSON.parse(item) : null;
} catch {
return null;
}
}
saveConsent(analytics, marketing) {
const consentState = {
analytics,
marketing,
timestamp: new Date().toISOString(),
version: 'v2'
};
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(consentState));
this.updateGoogleConsent(consentState);
this.removeBanner();
}
updateGoogleConsent(state) {
if (typeof gtag === 'function') {
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',
});
}
}
renderBanner() {
const bannerHtml = `
<div id="gdpr-banner" style="position:fixed; bottom:20px; right:20px; max-width:420px; background:#09090b; border:1px solid #27272a; padding:20px; border-radius:16px; color:#fff; font-family:sans-serif; z-index:99999; box-shadow:0 20px 25px -5px rgba(0,0,0,0.5);">
<h3 style="margin:0 0 8px 0; font-size:16px; font-weight:bold; color:#10b981;">Cookie & Privacy Preferences</h3>
<p style="font-size:12px; color:#a1a1aa; line-height:1.5; margin-bottom:16px;">
We respect your privacy. Under GDPR, non-essential cookies are disabled until you choose to accept them.
</p>
<div style="display:flex; gap:10px;">
<button id="gdpr-accept-all" style="flex:1; background:#10b981; color:#000; font-weight:bold; border:none; padding:10px; border-radius:8px; cursor:pointer;">Accept All</button>
<button id="gdpr-reject-all" style="flex:1; background:#27272a; color:#fff; font-weight:bold; border:none; padding:10px; border-radius:8px; cursor:pointer;">Reject Non-Essential</button>
</div>
</div>
`;
document.body.insertAdjacentHTML('beforeend', bannerHtml);
document.getElementById('gdpr-accept-all').addEventListener('click', () => {
this.saveConsent(true, true);
});
document.getElementById('gdpr-reject-all').addEventListener('click', () => {
this.saveConsent(false, false);
});
}
removeBanner() {
const elem = document.getElementById('gdpr-banner');
if (elem) elem.remove();
}
}
3. Compliance Verification Checklist
- Default consent set to
'denied'for analytics and advertising parameters. - Banner does not block access to core page content before interaction (no dark patterns).
- Preference selection stored locally in browser sandbox (
localStorage). - Users can re-open consent settings at any time from footer link.