Back to Blog

    Cookie Consent Implementation: Technical Guide for Developers

    Step-by-step technical guide for implementing GDPR and CCPA cookie consent banners. Includes JavaScript code, integration with Google Analytics, Facebook Pixel, and platform-specific solutions for WordPress, Shopify, and Next.js.

    Cookie Consent Implementation: Technical Guide for Developers
    October 15, 2025
    5 min read
    cookie-consent
    gdpr-compliance
    developer-guide
    javascript
    cookie-banner
    website-compliance
    gdpr
    ccpa google-analytics-consent
    hotjar-consent
    privacy-implementation
    cookie-consent-banner-code
    gdpr-cookie-implementation
    consent-javascript-example
    Share:

    Introduction

    If your website operates in Europe, California, or increasingly anywhere globally, cookie consent isn't optional—it's legally required. But implementing cookie consent the right way requires more than just slapping a banner on your site.

    Under GDPR, CCPA, and similar regulations, you must:

    1. Display a consent banner before loading tracking cookies

    2. Record which cookies users accepted

    3. Honor "reject all" and "manage preferences" options

    4. Allow users to change their mind anytime

    Get this wrong, and you're looking at regulatory fines and user distrust. Get it right, and you have compliant tracking plus a better user experience.

    This guide walks developers through exactly how to implement cookie consent—including code examples, best practices, and how to integrate with popular analytics platforms.


    Cookie consent is the practice of asking users' permission before storing certain cookies on their device. It's not about blocking all cookies—it's about being transparent and giving users control.

    The legal requirement is simple but often misunderstood: You must get explicit permission BEFORE placing tracking cookies, not after.

    This "ask first" approach is called "opt-in consent" and is required under GDPR, CCPA, ePrivacy Directive, and increasingly in other jurisdictions worldwide.

    Cookies That DON'T Require Consent:

    • Strictly necessary cookies (session management, security, CSRF tokens)

    • User preference cookies (language selection, dark mode)

    • Analytics cookies that don't identify individuals (truly anonymized, aggregated data)

    Cookies That REQUIRE Explicit Consent:

    • Marketing/advertising cookies (Google Ads, Facebook Pixel)

    • Remarketing pixels and retargeting cookies

    • Third-party analytics that can identify individuals (Google Analytics 4 with User-ID feature)

    • Heatmaps and session recording tools (Hotjar, Clarity, Logrocket)

    • A/B testing frameworks (Optimize, VWO)

    • Social media embed tracking cookies

    The Rule of Thumb: If a cookie can be used to identify or track a user across websites, it needs consent.

    GDPR (Europe)

    • Requires explicit opt-in consent before loading non-essential cookies

    • Users must be able to reject all with one click (equal to "accept all")

    • Consent must be freely given, specific, informed, and unambiguous

    • Cannot pre-check boxes or use dark patterns to manipulate consent

    CCPA (California)

    • Requires a "Do Not Sell or Share My Personal Information" link

    • Users must have the right to opt-out of data sales

    • Less strict than GDPR but still requires clear, conspicuous disclosures

    UKGDPR (United Kingdom)

    • Similar to GDPR with post-Brexit adjustments

    • Strict cookie consent requirements

    ePrivacy Directive (Electronic Privacy Directive)

    • Complements GDPR in Europe

    • Requires consent for cookies that store or access information


    Before writing code, understand the flow:

    User visits website
        ↓
    Script detects no prior consent
        ↓
    Display consent banner (before tracking scripts load)
        ↓
    User clicks "Accept All," "Reject All," or "Manage Preferences"
        ↓
    Store consent choice in browser storage or first-party cookie
        ↓
    Load appropriate tracking scripts based on consent
        ↓
    On return visit, check stored consent and load scripts automatically
    

    The critical piece: Tracking scripts must not load until consent is given.


    Pre-Implementation Audit: Know Your Cookies

    Before writing any code, you need to understand exactly what cookies your site currently sets. This determines what needs consent.

    Step 1: Identify All Cookies

    Use these methods:

    1. Browser DevTools: Open Chrome/Firefox DevTools → Application → Cookies. List every cookie and its source.

    2. Cookie Scanner Tools: Use free tools like CookieMetrix, OneTrust, or Cookiebot's scanner to automatically detect cookies.

    3. Google Tag Assistant: Chrome extension that identifies Google-related tags and cookies.

    4. Manual Review: Check all third-party integrations: analytics, ads, chatbots, CMS plugins, etc.

    Step 2: Categorize Cookies

    Create a spreadsheet:

    Cookie Name

    Source

    Category

    Purpose

    Duration

    Requires Consent?

    sessionid

    Your server

    Necessary

    Session management

    Session

    No

    _ga

    Google Analytics

    Analytics

    Track pageviews

    2 years

    Yes

    fbp

    Facebook Pixel

    Marketing

    Track conversions

    3 months

    Yes

    OptanonConsent

    OneTrust

    Consent

    Store consent choices

    1 year

    No

    Common Cookies by Category:

    Strictly Necessary (No Consent Required):

    • Session cookies (_session, JSESSIONID)

    • Security tokens (CSRF, XSRF tokens)

    • Authentication (auth_token, user_id)

    • Preference storage (language selection, theme preference)

    Analytics (Requires Consent):

    • ga, gat (Google Analytics)

    • _gid (Google Analytics session ID)

    • Mixpanel, Amplitude, Heap cookies

    • Hotjar, Clarity recording cookies

    Marketing (Requires Consent):

    • fbp, fr (Facebook Pixel)

    • _fbp (Facebook tracking)

    • Google Ads (_gac, gclid)

    • LinkedIn Insights (_lidc)

    • Twitter/X conversion tracking

    Step 3: Update Your Cookie Policy

    Your website's cookie policy should list every cookie, its purpose, and retention period. Example:

    "This site uses Google Analytics (_ga, _gat) to understand visitor behavior. These cookies are retained for 2 years and require your consent to set."


    Here's a basic, accessible consent banner structure:

    <div id="cookie-consent-banner" class="cookie-banner" role="dialog" aria-labelledby="cookie-title" aria-modal="true">
      <div class="cookie-banner__content">
        <h2 id="cookie-title">We Use Cookies</h2>
        <p>We use cookies to personalize content, analyze traffic, and remember your preferences. By clicking "Accept All," you consent to our use of cookies.</p>
        
        <div class="cookie-banner__links">
          <a href="/privacy-policy">Privacy Policy</a>
          <a href="/cookie-policy">Cookie Policy</a>
        </div>
      </div>
      
      <div class="cookie-banner__actions">
        <button id="cookie-reject-btn" class="cookie-btn cookie-btn--secondary">Reject All</button>
        <button id="cookie-manage-btn" class="cookie-btn cookie-btn--secondary">Manage Preferences</button>
        <button id="cookie-accept-btn" class="cookie-btn cookie-btn--primary">Accept All</button>
      </div>
    </div>
    
    <!-- Preferences Modal (hidden by default) -->
    <div id="cookie-preferences-modal" class="cookie-modal" hidden role="dialog" aria-labelledby="preferences-title" aria-modal="true">
      <div class="cookie-modal__content">
        <h2 id="preferences-title">Cookie Preferences</h2>
        
        <div class="cookie-category">
          <label>
            <input type="checkbox" id="necessary-cookies" checked disabled>
            <span>Strictly Necessary</span>
          </label>
          <p>Required for security, authentication, and site functionality. Cannot be disabled.</p>
        </div>
        
        <div class="cookie-category">
          <label>
            <input type="checkbox" id="analytics-cookies">
            <span>Analytics</span>
          </label>
          <p>Help us understand how visitors use our website. (Google Analytics)</p>
        </div>
        
        <div class="cookie-category">
          <label>
            <input type="checkbox" id="marketing-cookies">
            <span>Marketing</span>
          </label>
          <p>Used for advertising and retargeting across platforms. (Facebook Pixel, Google Ads)</p>
        </div>
      </div>
      
      <div class="cookie-modal__actions">
        <button id="preferences-cancel-btn" class="cookie-btn cookie-btn--secondary">Cancel</button>
        <button id="preferences-save-btn" class="cookie-btn cookie-btn--primary">Save Preferences</button>
      </div>
    </div>
    

    Key Accessibility Features:

    • role="dialog" and aria-modal="true" identify this as a modal for screen readers

    • aria-labelledby connects the modal to its heading

    • Buttons are keyboard-accessible and properly labeled

    • Checkbox states are clear and not pre-checked (except necessary)


    Store user preferences using a cookie or localStorage. This example uses both for broader browser compatibility:

    // Cookie utility functions
    const CookieConsent = {
      // Store consent preferences
      setConsent: function(preferences) {
        const consentData = {
          necessary: true, // Always true
          analytics: preferences.analytics || false,
          marketing: preferences.marketing || false,
          timestamp: new Date().toISOString(),
          version: '1.0'
        };
        
        // Store in sessionStorage (won't persist long-term)
        sessionStorage.setItem('cookieConsent', JSON.stringify(consentData));
        
        // Also store in a first-party cookie (expires in 365 days)
        const expires = new Date();
        expires.setTime(expires.getTime() + 365 * 24 * 60 * 60 * 1000);
        document.cookie = `cookieConsent=${JSON.stringify(consentData)}; path=/; expires=${expires.toUTCString()}; SameSite=Lax`;
      },
      
      // Retrieve stored consent
      getConsent: function() {
        // Try sessionStorage first
        const stored = sessionStorage.getItem('cookieConsent');
        if (stored) {
          return JSON.parse(stored);
        }
        
        // Fall back to cookie
        const name = 'cookieConsent=';
        const cookies = document.cookie.split(';');
        for (let cookie of cookies) {
          cookie = cookie.trim();
          if (cookie.indexOf(name) === 0) {
            try {
              return JSON.parse(decodeURIComponent(cookie.substring(name.length)));
            } catch (e) {
              console.warn('Failed to parse cookie consent:', e);
            }
          }
        }
        
        return null;
      },
      
      // Check if consent has been given
      hasConsent: function(category) {
        const consent = this.getConsent();
        return consent ? consent[category] : false;
      },
      
      // Clear consent (user can change preferences)
      clearConsent: function() {
        sessionStorage.removeItem('cookieConsent');
        document.cookie = 'cookieConsent=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC;';
      }
    };
    

    Implementation Step 3: Banner Display Logic

    Show the banner only if no prior consent exists:

    const ConsentBanner = {
      init: function() {
        // Check if user has already given consent
        if (CookieConsent.getConsent()) {
          this.hide();
          return;
        }
        
        // Show banner if no consent stored
        this.show();
        this.attachEventListeners();
      },
      
      show: function() {
        const banner = document.getElementById('cookie-consent-banner');
        if (banner) {
          banner.style.display = 'block';
          // Ensure banner is on top
          banner.style.zIndex = '9999';
        }
      },
      
      hide: function() {
        const banner = document.getElementById('cookie-consent-banner');
        if (banner) {
          banner.style.display = 'none';
        }
      },
      
      attachEventListeners: function() {
        const acceptBtn = document.getElementById('cookie-accept-btn');
        const rejectBtn = document.getElementById('cookie-reject-btn');
        const manageBtn = document.getElementById('cookie-manage-btn');
        
        acceptBtn?.addEventListener('click', () => this.acceptAll());
        rejectBtn?.addEventListener('click', () => this.rejectAll());
        manageBtn?.addEventListener('click', () => this.showPreferences());
      },
      
      acceptAll: function() {
        CookieConsent.setConsent({
          analytics: true,
          marketing: true
        });
        this.hide();
        TrackingScripts.loadAll();
      },
      
      rejectAll: function() {
        CookieConsent.setConsent({
          analytics: false,
          marketing: false
        });
        this.hide();
        TrackingScripts.loadNecessaryOnly();
      },
      
      showPreferences: function() {
        const modal = document.getElementById('cookie-preferences-modal');
        if (modal) {
          modal.hidden = false;
          this.populatePreferences();
        }
      },
      
      hidePreferences: function() {
        const modal = document.getElementById('cookie-preferences-modal');
        if (modal) {
          modal.hidden = true;
        }
      },
      
      populatePreferences: function() {
        const consent = CookieConsent.getConsent() || {};
        document.getElementById('analytics-cookies').checked = consent.analytics || false;
        document.getElementById('marketing-cookies').checked = consent.marketing || false;
      },
      
      savePreferences: function() {
        const preferences = {
          analytics: document.getElementById('analytics-cookies').checked,
          marketing: document.getElementById('marketing-cookies').checked
        };
        
        CookieConsent.setConsent(preferences);
        this.hidePreferences();
        this.hide();
        TrackingScripts.loadBased(preferences);
      }
    };
    
    // Preferences modal event listeners
    document.getElementById('cookie-preferences-modal')?.addEventListener('DOMContentLoaded', function() {
      document.getElementById('preferences-save-btn')?.addEventListener('click', () => {
        ConsentBanner.savePreferences();
      });
      
      document.getElementById('preferences-cancel-btn')?.addEventListener('click', () => {
        ConsentBanner.hidePreferences();
      });
    });
    
    // Initialize on page load
    document.addEventListener('DOMContentLoaded', () => ConsentBanner.init());
    

    Implementation Step 4: Conditional Loading of Tracking Scripts

    Only load tracking scripts if the user consented:

    const TrackingScripts = {
      // Load tracking based on consent
      loadBased: function(preferences) {
        if (preferences.analytics) {
          this.loadGoogleAnalytics();
        }
        if (preferences.marketing) {
          this.loadFacebookPixel();
          this.loadGoogleAds();
        }
      },
      
      loadAll: function() {
        this.loadGoogleAnalytics();
        this.loadFacebookPixel();
        this.loadGoogleAds();
      },
      
      loadNecessaryOnly: function() {
        // Load only essential, non-tracking scripts
        console.log('Only loading necessary scripts (no analytics/marketing)');
      },
      
      // Google Analytics (GA4)
      loadGoogleAnalytics: function() {
        const scriptId = 'G-XXXXXXXXXX'; // Replace with your GA4 ID
        
        // Only load if consent given
        if (!CookieConsent.hasConsent('analytics')) return;
        
        window.dataLayer = window.dataLayer || [];
        function gtag() {
          dataLayer.push(arguments);
        }
        gtag('js', new Date());
        gtag('config', scriptId, {
          'anonymize_ip': true // Best practice for privacy
        });
        
        // Add GA script
        const script = document.createElement('script');
        script.async = true;
        script.src = `https://www.googletagmanager.com/gtag/js?id=${scriptId}`;
        document.head.appendChild(script);
      },
      
      // Facebook Pixel
      loadFacebookPixel: function() {
        if (!CookieConsent.hasConsent('marketing')) return;
        
        const pixelId = '1234567890'; // Replace with your Pixel ID
        
        fbq = function() {
          fbq.callMethod ? fbq.callMethod.apply(fbq, arguments) : fbq.queue.push(arguments);
        };
        
        if (!window._fbq) window._fbq = fbq;
        fbq.push = fbq;
        fbq.loaded = !0;
        fbq.version = '2.0';
        fbq.queue = [];
        
        const script = document.createElement('script');
        script.async = true;
        script.src = 'https://connect.facebook.net/en_US/fbevents.js';
        document.head.appendChild(script);
        
        fbq('init', pixelId);
        fbq('track', 'PageView');
      },
      
      // Google Ads / Google Tag Manager
      loadGoogleAds: function() {
        if (!CookieConsent.hasConsent('marketing')) return;
        
        const gtmId = 'GTM-XXXXXXX'; // Replace with your GTM ID
        
        const script = document.createElement('script');
        script.async = true;
        script.src = `https://www.googletagmanager.com/gtm.js?id=${gtmId}`;
        document.head.appendChild(script);
      }
    };
    

    Google Analytics 4

    Load GA4 only after consent:

    // In your HTML head, add this BEFORE the GA script:
    window.dataLayer = window.dataLayer || [];
    
    // Then load analytics conditionally:
    if (CookieConsent.hasConsent('analytics')) {
      // GA script loads here
    }
    

    Google Tag Manager

    Wrap GTM implementation:

    // Check consent before loading GTM
    if (CookieConsent.hasConsent('marketing') || CookieConsent.hasConsent('analytics')) {
      (function(w, d, s, l, i) {
        w[l] = w[l] || [];
        w[l].push({'gtm.start': new Date().getTime(), event: 'gtm.js'});
        var f = d.getElementsByTagName(s)[0],
            j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : '';
        j.async = true;
        j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
        f.parentNode.insertBefore(j, f);
      })(window, document, 'script', 'dataLayer', 'GTM-XXXXXXX');
    }
    

    Hotjar (Session Recording)

    Hotjar must wait for consent:

    if (CookieConsent.hasConsent('marketing')) {
      window.hj = window.hj || function() {
        (hj.q = hj.q || []).push(arguments);
      };
      window._hjSettings = {
        hjid: 1234567,
        hjsv: 6
      };
      
      const a = document.createElement('script');
      a.async = true;
      a.src = 'https://static.hotjar.com/c/hotjar-' + window._hjSettings.hjid + '.js?sv=' + window._hjSettings.hjsv;
      document.head.appendChild(a);
    }
    

    Platform-Specific Solutions

    WordPress

    Plugin Option 1: Cookiebot

    • Automatically scans for cookies and compliance

    • Blocks cookies until consent

    • GDPR and CCPA compliant

    • Price: Free tier available, premium starts $10/month

    Plugin Option 2: WP Consent API

    • Open-source, free

    • Integrates with other WordPress plugins

    • Gives you full control over consent flow

    Manual Implementation: Add your consent script to wp-header.php:

    <?php wp_enqueue_script('cookie-consent', get_stylesheet_directory_uri() . '/js/cookie-consent.js', array(), '1.0', true); ?>
    

    Shopify

    In Shopify theme settings, add your consent script to theme.liquid or a custom app block:

    <!-- Add to Shopify theme -->
    <script src="https://yoursite.com/cookie-consent.js" defer></script>
    

    Next.js / React

    import { useEffect, useState } from 'react';
    
    export default function CookieConsent() {
      const [showBanner, setShowBanner] = useState(false);
    
      useEffect(() => {
        const consent = localStorage.getItem('cookieConsent');
        if (!consent) {
          setShowBanner(true);
        }
      }, []);
    
      const handleAccept = () => {
        localStorage.setItem('cookieConsent', JSON.stringify({
          analytics: true,
          marketing: true,
          timestamp: new Date().toISOString()
        }));
        setShowBanner(false);
        // Load tracking scripts here
      };
    
      if (!showBanner) return null;
    
      return (
        <div className="cookie-banner">
          <p>We use cookies to enhance your experience...</p>
          <button onClick={handleAccept}>Accept All</button>
        </div>
      );
    }
    

    CSS Styling Best Practices

    Make your banner visible but not obnoxiously intrusive:

    .cookie-banner {
      position: fixed;
      bottom: 0;
      left: 0;
      right: 0;
      background: #ffffff;
      border-top: 1px solid #e0e0e0;
      padding: 1.5rem;
      box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.1);
      z-index: 9999;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    }
    
    .cookie-banner__content {
      max-width: 900px;
      margin: 0 auto 1rem;
    }
    
    .cookie-banner__content h2 {
      margin: 0 0 0.5rem;
      font-size: 1.125rem;
      font-weight: 600;
    }
    
    .cookie-banner__content p {
      margin: 0 0 1rem;
      color: #424242;
      line-height: 1.5;
    }
    
    .cookie-banner__actions {
      display: flex;
      gap: 1rem;
      justify-content: flex-end;
    }
    
    .cookie-btn {
      padding: 0.75rem 1.5rem;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-weight: 500;
      white-space: nowrap;
      transition: all 0.2s;
    }
    
    .cookie-btn--primary {
      background: #1976d2;
      color: white;
    }
    
    .cookie-btn--primary:hover {
      background: #1565c0;
    }
    
    .cookie-btn--secondary {
      background: #f0f0f0;
      color: #333;
      border: 1px solid #e0e0e0;
    }
    
    .cookie-btn--secondary:hover {
      background: #e8e8e8;
    }
    
    /* Mobile responsiveness */
    @media (max-width: 640px) {
      .cookie-banner {
        padding: 1rem;
      }
      
      .cookie-banner__actions {
        flex-wrap: wrap;
      }
      
      .cookie-btn {
        flex: 1;
        min-width: 120px;
      }
    }
    
    /* Modal for preferences */
    .cookie-modal {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background: white;
      padding: 2rem;
      border-radius: 8px;
      box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
      max-width: 500px;
      max-height: 80vh;
      overflow-y: auto;
      z-index: 10000;
    }
    
    .cookie-modal::backdrop {
      background: rgba(0, 0, 0, 0.5);
    }
    
    .cookie-category {
      margin-bottom: 1.5rem;
    }
    
    .cookie-category label {
      display: flex;
      align-items: center;
      gap: 0.75rem;
      cursor: pointer;
      font-weight: 500;
    }
    
    .cookie-category p {
      margin: 0.5rem 0 0 2rem;
      color: #666;
      font-size: 0.875rem;
    }
    

    Testing Your Implementation

    Checklist for Testing

    • [ ] Banner displays on first visit

    • [ ] Banner doesn't display on repeat visits

    • [ ] "Accept All" loads all tracking scripts

    • [ ] "Reject All" only loads necessary scripts

    • [ ] "Manage Preferences" modal opens and displays correctly

    • [ ] Saved preferences are remembered across page reloads

    • [ ] Users can change preferences anytime

    • [ ] Preference changes take effect immediately

    • [ ] Google Analytics only fires after consent

    • [ ] Facebook Pixel only fires after consent

    • [ ] Banner is responsive on mobile

    • [ ] Banner is keyboard accessible

    • [ ] No tracking scripts are loaded before consent (check Network tab)

    Browser DevTools Testing

    Chrome DevTools - Application tab:

    1. Open DevTools → Application

    2. Check Storage → Cookies and localStorage for your consent data

    3. Clear consent and reload to verify banner reappears

    4. Check Network tab to confirm tracking scripts don't load until consent is given

    Testing Script Blocking:

    // Run in browser console to verify tracking scripts haven't loaded yet
    console.log('GA loaded:', typeof gtag === 'function');
    console.log('Facebook Pixel loaded:', typeof fbq === 'function');
    

    Common Implementation Mistakes to Avoid

    Mistake 1: Pre-checked "Accept All" Never pre-check the accept box. GDPR requires active opt-in, not opt-out.

    Mistake 2: Making "Reject" Hard to Find Ensure reject is equally visible and easy to click as accept. Dark patterns violate GDPR.

    Mistake 3: Loading Tracking Scripts Before Consent If Google Analytics loads before checking consent, you're already in violation. Check your script loading order.

    Mistake 4: Not Storing Preferences Users should only see the banner once. Store their choice.

    Mistake 5: Burying the Cookie Policy Link to your full cookie policy from the banner. Users need to understand what they're consenting to.

    Mistake 6: Expiring Consent Too Quickly GDPR doesn't specify how long consent lasts, but best practice is 12 months. Reassess yearly or after major changes.

    Mistake 7: Not Giving Users a Way to Change Consent Add a "Cookie Settings" link in your footer that users can click anytime to update preferences.


    Compliance Verification Checklist

    • [ ] Consent banner appears before any non-essential cookies load

    • [ ] Reject all is as easy as accept all (no dark patterns)

    • [ ] Privacy policy and cookie policy are linked from banner

    • [ ] Consent choices are stored and remembered

    • [ ] Users can change preferences anytime

    • [ ] "Necessary only" mode works without analytics/marketing

    • [ ] Consent is version-tracked (in case of policy changes)

    • [ ] Banner is WCAG 2.1 AA accessible

    • [ ] No third-party tracking until explicit consent

    • [ ] Consent is documented for audit purposes


    Monitoring and Maintenance

    Monthly:

    • Verify consent banner displays correctly

    • Check that no unauthorized tracking scripts are loading

    • Review consent rates (tools like Hotjar show this)

    Quarterly:

    • Audit your third-party integrations for new tracking cookies

    • Review consent data storage for GDPR compliance

    • Test on different browsers and devices

    Annually:

    • Renew consent prompt (best practice)

    • Review and update privacy/cookie policies

    • Test full implementation from scratch


    Ready-Made Solutions:

    • Cookiebot: $10-25/month, fully managed

    • OneTrust: Enterprise solution, $500+/month

    • TrustArc: Compliance platform, enterprise pricing

    • Osano: Privacy management platform, $99/month

    Open-Source Libraries:

    • CookieConsent.com: Free, lightweight (~2.5KB)

    • Tinycc: Minimal cookie consent, <1KB

    • Axeptio: Open-source option available

    • iubenda: GDPR/CCPA solution, €12-99/month

    DIY Option: Build your own using the code in this guide—it gives you maximum control and costs nothing beyond development time.


    Q: What if I'm a small site with no tracking? A: You still need a banner if you use any cookies, including session cookies. However, you can simplify to: "This site uses cookies for basic functionality. Accept?"

    Q: Can I use Google Consent Mode instead of building my own? A: Google Consent Mode helps, but it's not sufficient on its own for full GDPR compliance. Use it in addition to your own consent implementation.

    Q: Should I use a cookie consent platform or build my own? A: Platforms are easier but cost money. DIY gives you control. For most small businesses, a lightweight platform ($10-20/month) is worth it for peace of mind and updates.

    Q: What if my user has JavaScript disabled? A: This is rare (<1% of users), but for maximum compliance, include a no-script fallback: <noscript><p>Please enable JavaScript to use this site.</p></noscript>

    Q: How long should I keep consent records? A: GDPR best practice is 12 months. Keep logs showing who consented, when, and to what.

    Q: Can I automatically reconsent users annually? A: Yes, it's best practice. Most platforms re-prompt users yearly or when your privacy policy changes.

    Q: Do I need different consent for different regions? A: Technically yes, but practically, GDPR is the strictest—if you comply with GDPR, you're likely compliant elsewhere. Exception: COPPA requires separate parental consent for children under 13.


    Next Steps

    1. Audit your current cookies: Use browser DevTools to list all cookies your site sets

    2. Map cookies to categories: Necessary, analytics, or marketing

    3. Choose your implementation: Platform (easier) or DIY (cheaper)

    4. Implement and test: Use the checklist above

    5. Document everything: Keep records of your implementation for compliance audits

    6. Set a calendar reminder: Review and update quarterly

    Your cookie implementation is the foundation of privacy compliance. Get it right once, and you'll sleep better at night.

    Legal compliance expert contributing to PolicyForge insights.

    Legal Compliance

    Related Posts

    EU AI Act Compliance: What Your Privacy Policy and Disclaimers Need in 2026

    The EU AI Act transparency rules take effect August 2026. Learn exactly what your privacy policy and disclaimers must include, the penalty tiers, and a 10-step compliance checklist.

    4/8/20265 min read

    Do You Need an AI Disclaimer in 2026? Here's What the Law Says

    New regulations from the EU AI Act, FTC, and Colorado AI Act are making AI disclaimers a legal requirement for businesses in 2026. This guide covers when you're legally required to disclose AI use, when you should even without a mandate, and the five elements every AI disclaimer needs. Includes real examples and a free generator to create yours in minutes.

    4/8/20265 min read

    How to Disclose AI Use in Your Privacy Policy (With Examples and Templates) | PolicyForge

    Most products use AI but most privacy policies don't mention it. This guide covers the five sections every AI-using business needs to add, with copy-paste template language for each. Covers recommendation engines, chatbots, content generation, model training disclosures, automated decision-making, and accuracy limitations.

    4/8/20265 min read

    Ready to generate your legal policies?

    Create compliant privacy policies, terms of service, and more with AI assistance.