Part of our Compliance & Regulation series
Read the complete guideOver EUR 400 million in GDPR fines have been issued specifically for cookie consent violations since 2020. The French CNIL fined Google EUR 150 million and Facebook EUR 60 million for making it easier to accept cookies than to refuse them. Cookie consent is no longer a checkbox exercise --- it is a heavily enforced area of privacy law with specific technical requirements.
This guide covers the legal requirements, technical implementation, and ongoing management of cookie consent for websites and web applications.
Key Takeaways
- Under GDPR and ePrivacy, consent must be obtained BEFORE setting non-essential cookies --- not after
- Consent must be as easy to withdraw as it is to give (one-click refuse, not buried in settings)
- Cookie walls ("accept or leave") are illegal in most EU member states
- Google Consent Mode v2 is required for Google Analytics and Ads in the EEA since March 2024
Legal Requirements by Region
Cookie Consent Requirements Comparison
| Requirement | EU (GDPR + ePrivacy) | UK (PECR + UK GDPR) | US (CCPA/state laws) | Brazil (LGPD) | Canada (PIPEDA) |
|---|---|---|---|---|---|
| Prior consent for non-essential cookies | Yes (opt-in) | Yes (opt-in) | No (opt-out model) | Yes (opt-in) | Implied consent allowed |
| Consent banner required | Yes | Yes | Not required (but recommended) | Yes | Recommended |
| Granular choices (by category) | Yes | Yes | Not required | Yes | Recommended |
| Equal prominence for accept/refuse | Yes | Yes | N/A | Yes | N/A |
| Cookie wall allowed | No (in most states) | No | N/A | No | N/A |
| Consent record required | Yes | Yes | No | Yes | Yes |
| Consent renewal period | Max 12 months | Max 12 months | N/A | Not specified | Not specified |
| Cookie policy required | Yes (detailed) | Yes (detailed) | Yes (if tracking) | Yes | Yes |
What Counts as a Cookie
The ePrivacy Directive covers not just HTTP cookies but all technologies that store or access information on the user's device:
- HTTP cookies (first-party and third-party)
- LocalStorage and SessionStorage
- IndexedDB
- Device fingerprinting
- Tracking pixels / web beacons
- ETags used for tracking
Cookie Categorization
Standard Categories
| Category | Consent Required? | Examples | Default State |
|---|---|---|---|
| Strictly necessary | No | Session cookies, CSRF tokens, load balancer cookies, authentication | Always on |
| Functional / preferences | Yes | Language preference, theme preference, saved cart | Off (until consent) |
| Analytics / performance | Yes | Google Analytics, Hotjar, Plausible (with cookies) | Off (until consent) |
| Marketing / advertising | Yes | Google Ads, Facebook Pixel, retargeting cookies | Off (until consent) |
Auditing Your Cookies
Before implementing consent, audit every cookie your website sets:
// Browser console: list all cookies
document.cookie.split(';').forEach(c => console.log(c.trim()));
// Or use a scanning tool
// cookiebot.com/en/cookie-checker
// 2gdpr.com
Document each cookie:
| Cookie Name | Category | Purpose | Duration | First/Third Party |
|---|---|---|---|---|
ecosire_auth | Strictly necessary | Authentication | Session | First-party |
ecosire_refresh | Strictly necessary | Token refresh | 7 days | First-party |
NEXT_LOCALE | Strictly necessary | Language preference | 1 year | First-party |
_ga | Analytics | Google Analytics visitor ID | 2 years | Third-party (Google) |
_fbp | Marketing | Facebook Pixel tracking | 90 days | Third-party (Facebook) |
Technical Implementation
Option 1: Consent Management Platform (CMP)
| CMP | Free Tier | GDPR Compliant | Google CMP Partner | IAB TCF 2.2 |
|---|---|---|---|---|
| Cookiebot | Up to 1 page | Yes | Yes | Yes |
| OneTrust | No | Yes | Yes | Yes |
| Osano | Up to 5K visitors | Yes | Yes | No |
| Termly | Basic plan | Yes | Yes | No |
| Cookie-Script | Up to 1 site | Yes | Yes | No |
Option 2: Custom Implementation
For teams that want full control:
// lib/cookie-consent.ts
type ConsentCategory = 'necessary' | 'functional' | 'analytics' | 'marketing';
interface ConsentPreferences {
necessary: true; // Always true, cannot be changed
functional: boolean;
analytics: boolean;
marketing: boolean;
timestamp: string;
version: string;
}
const CONSENT_COOKIE = 'ecosire_consent';
const CONSENT_VERSION = '2.0';
const CONSENT_DURATION = 365; // days
export function getConsent(): ConsentPreferences | null {
const cookie = document.cookie
.split(';')
.find(c => c.trim().startsWith(`${CONSENT_COOKIE}=`));
if (!cookie) return null;
try {
const prefs = JSON.parse(decodeURIComponent(cookie.split('=')[1]));
// Invalidate if consent version changed
if (prefs.version !== CONSENT_VERSION) return null;
return prefs;
} catch {
return null;
}
}
export function setConsent(preferences: Omit<ConsentPreferences, 'necessary' | 'timestamp' | 'version'>) {
const consent: ConsentPreferences = {
necessary: true,
...preferences,
timestamp: new Date().toISOString(),
version: CONSENT_VERSION,
};
const expires = new Date(Date.now() + CONSENT_DURATION * 86400000).toUTCString();
document.cookie = `${CONSENT_COOKIE}=${encodeURIComponent(JSON.stringify(consent))}; expires=${expires}; path=/; SameSite=Lax`;
// Apply consent decisions
applyConsent(consent);
return consent;
}
function applyConsent(consent: ConsentPreferences) {
if (consent.analytics) {
// Initialize Google Analytics
loadScript('https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX');
}
if (consent.marketing) {
// Initialize marketing pixels
loadScript('https://connect.facebook.net/en_US/fbevents.js');
}
if (!consent.analytics) {
// Remove analytics cookies
deleteCookie('_ga');
deleteCookie('_gid');
}
if (!consent.marketing) {
// Remove marketing cookies
deleteCookie('_fbp');
deleteCookie('_fbc');
}
}
Google Consent Mode v2
Required for Google Analytics and Google Ads in the EEA since March 2024:
<!-- Set default consent state BEFORE loading Google tags -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
// Default: deny all until user consents
gtag('consent', 'default', {
'ad_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'analytics_storage': 'denied',
'functionality_storage': 'denied',
'personalization_storage': 'denied',
'security_storage': 'granted', // Always granted (necessary)
'wait_for_update': 500 // Wait for CMP
});
</script>
<!-- Load Google Tag Manager -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
When the user provides consent:
// Update consent state when user interacts with banner
function updateGoogleConsent(preferences) {
gtag('consent', 'update', {
'ad_storage': preferences.marketing ? 'granted' : 'denied',
'ad_user_data': preferences.marketing ? 'granted' : 'denied',
'ad_personalization': preferences.marketing ? 'granted' : 'denied',
'analytics_storage': preferences.analytics ? 'granted' : 'denied',
'functionality_storage': preferences.functional ? 'granted' : 'denied',
'personalization_storage': preferences.functional ? 'granted' : 'denied',
});
}
Consent Banner Design Requirements
EU Legal Requirements
- Banner appears BEFORE any non-essential cookies are set
- "Accept all" and "Refuse all" buttons have equal visual prominence
- Granular category selection available (not just all-or-nothing)
- No pre-checked boxes for non-essential categories
- Clear, plain language explanation of each category
- Link to full cookie policy
- Consent withdrawal accessible at any time (e.g., footer link)
- No cookie wall (must be able to use the site without consenting)
- Consent recorded with timestamp and version
Accessibility Requirements
- Banner is keyboard navigable
- Screen reader compatible (ARIA labels)
- Sufficient color contrast
- Does not block essential content permanently
Cookie-Free Analytics Alternative
For websites wanting to avoid cookie consent banners entirely:
| Tool | Cookies | GDPR Consent Needed | Data Location | Price |
|---|---|---|---|---|
| Plausible | None | No | EU | $9/month |
| Fathom | None | No | EU/US/Canada | $14/month |
| Umami | None | No | Self-hosted | Free |
| Simple Analytics | None | No | EU | $9/month |
| Matomo (cookie-free config) | Optional | No (without cookies) | Self-hosted | Free |
Using cookie-free analytics eliminates the need for analytics consent, simplifying your consent banner to only cover marketing cookies (if used).
Frequently Asked Questions
Do we need a cookie banner if we only use necessary cookies?
No. If you only use strictly necessary cookies (authentication, CSRF, load balancing), no consent is required and no banner is needed. However, you should still disclose these cookies in your privacy policy. The moment you add analytics (Google Analytics) or any third-party tracking, a consent banner becomes legally required in the EU.
Is it legal to use a "soft opt-in" (continue browsing = consent)?
No, not under GDPR. The European Data Protection Board has explicitly stated that continued browsing, scrolling, or similar passive actions do not constitute valid consent. Consent must be a clear, affirmative action --- clicking a button that says "Accept" or similar. Soft opt-in was ruled non-compliant in Planet49 (CJEU, 2019).
How do we handle consent for single-page applications?
For SPAs, check consent state on initial page load and on every route change. If consent has not been given, do not initialize tracking scripts. Store consent preferences in a first-party cookie (which itself is strictly necessary for remembering consent). When the user provides consent, initialize tracking scripts without requiring a page reload.
Do we need cookie consent for our Odoo website?
If your Odoo website serves EU visitors and uses analytics, marketing pixels, or functional cookies beyond what is strictly necessary, yes. Odoo has a basic cookie notice but it does not meet GDPR standards. Implement a proper CMP like Cookiebot or build a custom solution. ECOSIRE provides Odoo website services that include GDPR-compliant cookie consent.
What Comes Next
Cookie consent is the most visible aspect of web privacy compliance. Combine it with privacy by design for your application architecture, data governance for your full data program, and cybersecurity regulations for broader compliance.
Contact ECOSIRE for cookie consent implementation and privacy compliance consulting.
Published by ECOSIRE -- helping businesses implement privacy compliance that users trust.
Written by
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
ECOSIRE
Grow Your Business with ECOSIRE
Enterprise solutions across ERP, eCommerce, AI, analytics, and automation.
Related Articles
BMF Programmablaufplan Lohnsteuer 2026: Implementing Germany's Official Wage-Tax Calculation (XML, API, Odoo)
Developer guide to the BMF Programmablaufplan Lohnsteuer 2026: what the PAP is, the XML pseudocode format, official test service, and mapping to Odoo payroll.
ERP for Clothing & Fashion Brands: Size-Color Matrix, Seasonal Planning, and Compliance (2026 Guide)
How fashion and clothing brands choose an ERP in 2026: size-color matrix variants, seasonal planning, GoBD and DATEV compliance, vendor comparison, and costs.
ERPNext HR & Payroll in 2026: Setup, Salary Structures, and Multi-Country Compliance
Step-by-step ERPNext HR and payroll setup for 2026: HRMS app install, salary structures, payroll entry runs, income tax slabs, multi-country compliance.
More from Compliance & Regulation
BMF Programmablaufplan Lohnsteuer 2026: Implementing Germany's Official Wage-Tax Calculation (XML, API, Odoo)
Developer guide to the BMF Programmablaufplan Lohnsteuer 2026: what the PAP is, the XML pseudocode format, official test service, and mapping to Odoo payroll.
ERP for Clothing & Fashion Brands: Size-Color Matrix, Seasonal Planning, and Compliance (2026 Guide)
How fashion and clothing brands choose an ERP in 2026: size-color matrix variants, seasonal planning, GoBD and DATEV compliance, vendor comparison, and costs.
ERPNext HR & Payroll in 2026: Setup, Salary Structures, and Multi-Country Compliance
Step-by-step ERPNext HR and payroll setup for 2026: HRMS app install, salary structures, payroll entry runs, income tax slabs, multi-country compliance.
GoHighLevel A2P 10DLC Compliance in 2026: Registration, Fees, and Fixing Blocked SMS
Complete GoHighLevel A2P 10DLC guide for 2026: brand and campaign registration steps, carrier fees, common rejection reasons, and how to fix filtered SMS.
GxP Validation for ERP Systems: What Your 2026 Validation RFP Must Require (CSV, IQ/OQ/PQ, Audit Trails)
What a GxP ERP validation RFP must require in 2026: CSV and CSA scope, 21 CFR Part 11, EU Annex 11, IQ/OQ/PQ deliverables, audit trails, and GAMP 5 risk.
OpenClaw Security Model, Data Residency, SOC 2 and ISO 27001
OpenClaw security architecture: tenant isolation, encryption, secret management, audit logs, data residency, SOC 2, ISO 27001, GDPR, HIPAA fitness.