GDPR-compliant cookie consent management with category-based controls and persistent storage for both anonymous and authenticated users.

The consent state is stored under the cookie key cookie_consent (set by components/cookie-consent.tsx and read by components/analytics/analytics-provider.tsx). The same key is mirrored in localStorage so the analytics provider can restore prior consent before any third-party script mounts and re-applies Google Consent Mode v2 signals. For authenticated users, the choices are additionally persisted to the user_consents table via POST /api/user/consents.

The consent dialog also checks browser Global Privacy Control. When navigator.globalPrivacyControl is true, marketing consent is forced off and the marketing toggle is disabled. This keeps sale, sharing, cross-context behavioral advertising, and targeted-advertising opt-out semantics aligned with the public /[locale]/privacy-choices page.

Cookie Categories

Category Default Description
Necessary Always On Essential cookies for site functionality (session, auth, locale)
Analytics Opt-in Google Tag Manager, usage statistics
Marketing Opt-in Google Ads conversions, Meta Pixel, advertising cookies, remarketing

How It Works

  1. Banner Display - Shows on first visit if no consent recorded
  2. User Choice - Accept all, reject non-essential, or customize by category
  3. Persistence - Stored in cookie + localStorage for anonymous users
  4. Database Sync - For logged-in users, consent is saved through POST /api/user/consents, not by a browser-side Supabase upsert
  5. Third-party Loading - GTM, gtag/Google Ads, Meta, X and Crisp mount only after the matching consent category is granted
  6. Consent Mode - Consent state is pushed via Consent Mode v2 (analytics_storage, ad_storage, ad_user_data, ad_personalization)
  7. Global Privacy Control - Browser GPC signals keep marketing/sharing/targeted-ad consent disabled even if the visitor clicks accept all
  8. Withdrawal - The footer Cookie settings control reopens the preference dialog after the banner has been dismissed

Preference Management

Users can update their preferences at any time via:

  • Footer Cookie settings control
  • Footer Your Privacy Choices link
  • My Account page privacy section
  • Clicking the cookie banner again (if not dismissed permanently)

Cookie Security & Accessibility

The consent cookie is set with the Secure flag in production, ensuring it is only transmitted over HTTPS. The cookie banner and preference modal implement full ARIA accessibility: role="dialog", aria-label, focus trapping, and keyboard-navigable category toggles.

Consent Mode v2 Strategy

Google Consent Mode v2 is implemented with a deny-by-default strategy. On page load, analytics_storage, ad_storage, ad_user_data, and ad_personalization are all set to denied. When the user grants consent for a category, the corresponding consent signals are updated to granted via gtag('consent', 'update', ...), then the relevant third-party script can mount. This keeps the implementation aligned with stricter EU/Swiss privacy-by-default interpretations.