Type something to search...
How to Set Up GDPR Cookie Consent in WordPress?

How to Set Up GDPR Cookie Consent in WordPress?

GDPR requires real opt-in consent before non-essential cookies load, and most WordPress sites still get this wrong by tracking visitors by default. A cookie notice banner that just says "we use cookies, by continuing to browse you agree" isn't consent under GDPR, it's a formality with no legal weight, because Google Analytics, Google Tag Manager, and most third-party embeds are already dropping cookies on the visitor's browser before that banner even finishes loading.

If you have visitors from the EU or UK (and realistically, almost every public website does), you need consent captured before non-essential cookies are set, not after. That distinction, before versus after, is the entire difference between a compliant cookie banner and a decorative one. This guide covers what GDPR actually requires, the plugins that handle it well out of the box, and how to build the underlying mechanism yourself if you'd rather understand exactly what's happening under the hood.

What GDPR Actually Requires for Cookies

The GDPR itself doesn't mention cookies directly; the specific cookie rules come from the ePrivacy Directive (often called the "Cookie Law"), which GDPR's consent standard has effectively absorbed and toughened. Together, they require a few concrete things:

  • Consent must be given before non-essential cookies are set, not implied by continued browsing and not granted by default with an opt-out toggle.
  • Consent must be specific and informed. A visitor needs to know what categories of cookies they're agreeing to (analytics, marketing, functional), not just a generic "cookies" blanket statement.
  • Declining must be as easy as accepting. A banner with a prominent "Accept All" button and a buried, multi-click path to reject everything doesn't meet this bar; regulators have fined companies specifically over this pattern.
  • Strictly necessary cookies are exempt. Things like a session cookie needed for a shopping cart to function, or a cookie storing the visitor's own consent choice, don't require opt-in consent because the site can't function without them.
  • Consent needs to be recorded and, ideally, easy to withdraw. Visitors should be able to change their mind later, typically through a "Cookie Settings" link in the footer.

Practically, this breaks cookies into categories: strictly necessary (always on), analytics (Google Analytics, Hotjar, etc.), functional (embedded video players, chat widgets), and marketing (ad pixels, retargeting scripts). Anything outside the necessary category needs to wait for explicit, affirmative consent before it loads.

Option 1: Use a Dedicated Cookie Consent Plugin

For most sites, a plugin is the right call, since building and maintaining a fully compliant consent management platform (with geo-targeted banners, a consent log, and automatic script-blocking) yourself is a lot of ongoing work for something that isn't your core product. Three plugins are worth knowing:

  • CookieYes is one of the most widely used options, with a free tier that covers a customizable banner, automatic cookie scanning, and Google's Consent Mode integration, which matters specifically because it lets Google Analytics and Google Ads adjust their own behavior based on the consent state rather than firing unconditionally.
  • Complianz takes a more thorough, wizard-driven approach, walking you through a questionnaire about your jurisdiction and the services you use, then generating both the banner and a matching privacy policy. It also handles script-blocking automatically for common services like YouTube embeds and Google Fonts.
  • GDPR Cookie Consent by WebToffee is a lighter option that still covers the essentials: a categorized banner, a script-blocking mechanism based on cookie category, and a shortcode for a "Cookie Settings" reopen link.

All three work on the same underlying principle: they inject a banner before any tracking scripts fire, hold those scripts back using a script-blocking technique (usually swapping <script src="..."> for <script type="text/plain" data-cookie-category="..."> until consent is granted), and only let the real script tag activate once the visitor picks a category.

Option 2: Build a Consent-Gated Analytics Loader Yourself

If your only real tracking dependency is Google Analytics or Google Tag Manager (a common case if you followed our guide on how to add Google Analytics to a WordPress website), a full consent management plugin can be more than you need. Here's a minimal, working approach: a footer banner that sets a cookie recording the visitor's choice, and a script enqueue that only fires once that cookie says "granted."

Step 1: Output the Consent Banner

Add this to your theme's functions.php:

add_action( 'wp_footer', function () {
    if ( isset( $_COOKIE['tw_cookie_consent'] ) ) {
        return;
    }
    ?>
    <div id="tw-cookie-banner" class="tw-cookie-banner" role="dialog" aria-label="Cookie consent">
        <p>
            We use cookies to analyze site traffic and improve your experience.
            Read our <a href="/privacy-policy">privacy policy</a> to learn more.
        </p>
        <div class="tw-cookie-banner__actions">
            <button id="tw-cookie-decline" type="button">Decline</button>
            <button id="tw-cookie-accept" type="button">Accept</button>
        </div>
    </div>
    <script>
    document.addEventListener( 'DOMContentLoaded', function () {
        var banner = document.getElementById( 'tw-cookie-banner' );

        function setConsent( value ) {
            var maxAge = 60 * 60 * 24 * 180; // 180 days
            document.cookie = 'tw_cookie_consent=' + value + ';path=/;max-age=' + maxAge + ';SameSite=Lax';
            banner.style.display = 'none';

            if ( value === 'granted' ) {
                window.location.reload();
            }
        }

        document.getElementById( 'tw-cookie-accept' ).addEventListener( 'click', function () {
            setConsent( 'granted' );
        } );

        document.getElementById( 'tw-cookie-decline' ).addEventListener( 'click', function () {
            setConsent( 'denied' );
        } );
    } );
    </script>
    <?php
} );

A couple of implementation details worth calling out:

  • The isset( $_COOKIE['tw_cookie_consent'] ) check at the top means the banner only renders for visitors who haven't made a choice yet. Once a cookie exists, whether it's granted or denied, the banner stays hidden on future visits.
  • window.location.reload() after accepting is what triggers the page to reload with the consent cookie now present, so the PHP-side check in the next step (which reads $_COOKIE on page load) sees it and enqueues the tracking script. This is the "before, not after" requirement in practice: Analytics never loads on the same page view where consent was just given, only on the next request.
  • SameSite=Lax on the cookie is a sensible default for a first-party consent cookie like this one; it doesn't need Secure unless your entire site is served over HTTPS with no HTTP fallback, though in 2026 that should be true of essentially every site.

Step 2: Gate the Analytics Script Behind the Consent Cookie

Now add the actual tracking script, but only enqueue it when the consent cookie says granted:

add_action( 'wp_enqueue_scripts', function () {
    if ( ! isset( $_COOKIE['tw_cookie_consent'] ) || 'granted' !== $_COOKIE['tw_cookie_consent'] ) {
        return;
    }

    wp_enqueue_script(
        'tw-gtag',
        'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX',
        [],
        null,
        true
    );

    wp_add_inline_script( 'tw-gtag', "
        window.dataLayer = window.dataLayer || [];
        function gtag(){ dataLayer.push(arguments); }
        gtag('js', new Date());
        gtag('config', 'G-XXXXXXX');
    " );
} );

Because this check runs entirely in PHP before any markup is sent to the browser, a visitor who declined or hasn't yet responded never receives the gtag.js script tag at all, rather than receiving it and having client-side JavaScript try to block it after the fact. That's a meaningfully stronger guarantee than banner plugins that rely purely on intercepting script tags client-side, though it does mean the reload step in Step 1 is necessary to apply the change.

Step 3: Add a "Manage Cookie Preferences" Link

GDPR expects visitors to be able to change their mind. A simple shortcode reopens the banner by clearing the cookie:

add_shortcode( 'cookie_settings', function () {
    return '<button onclick="document.cookie=\'tw_cookie_consent=;path=/;max-age=0\';window.location.reload();" class="tw-cookie-settings-link">Manage Cookie Preferences</button>';
} );

Placing [cookie_settings] in your footer widget area or a footer template gives visitors a permanent way back into the banner, which most privacy policies (and several EU regulators' guidance) explicitly expect a site to provide.

Which Approach Should You Actually Use?

If you're only running Google Analytics or GTM and want to fully understand and control the mechanism, the custom approach above is genuinely sufficient and keeps your site free of another plugin dependency. But if you're running multiple third-party scripts (a chat widget, an ad pixel, embedded video, a CRM tracking snippet), a plugin like CookieYes or Complianz is worth the dependency, since manually gating every single script individually gets tedious and error-prone fast, and these plugins also generate the consent log and cookie policy page that a full compliance posture requires.

Either way, cookie consent is only one piece of a broader privacy and security posture. It's worth reviewing our guide on how to secure your WordPress website as well, since a compliant cookie banner sitting on top of an insecure site protects you from the wrong kind of risk.

Frequently Asked Questions (FAQ) About GDPR Cookie Consent in WordPress

Technically, GDPR applies based on where your visitors are located, not where your business is based, so if you genuinely have zero visitors from the EU or UK you may not be legally required to comply with GDPR specifically. In practice, almost no public website can reliably guarantee that, and several other jurisdictions (the UK's PECR, California's CCPA for a different but related purpose) have their own similar requirements, so most sites implement consent regardless.

Yes. Google Analytics sets first-party cookies (like _ga and ga*) specifically to identify and track visitors across sessions, which places it squarely in the "analytics" category that requires opt-in consent under GDPR, not the "strictly necessary" exemption.

A cookie banner controls whether a script loads at all. Google's Consent Mode is a separate signal you send to Google's tags (Analytics, Ads) indicating the visitor's consent state, which lets those tags adjust their own behavior, for example by sending anonymized, cookieless pings instead of full tracking data when consent is denied. Plugins like CookieYes integrate directly with Consent Mode; the custom functions.php approach in this guide handles the simpler case of loading gtag.js at all, which covers most small to mid-sized sites.

No, this is exactly the kind of dark pattern that fails GDPR's "freely given" consent standard. Consent has to come from an affirmative action the visitor takes, like clicking Accept, not from inaction, a timeout, or continued scrolling.

Your reported traffic numbers will reflect only visitors who consented, which is typically lower than your actual traffic, sometimes significantly so depending on your audience and region. This is an expected and legally required trade-off, not a bug; Google's Consent Mode partially mitigates the gap with modeled, aggregated estimates for visitors who declined.

There's no single legally mandated number, but most guidance (and most consent management plugins) default to somewhere between 6 and 12 months. The 180-day max-age used in the example above sits comfortably inside that range; adjust it based on your own privacy policy's stated retention period.

Generally no. Strictly necessary cookies, meaning ones without which the requested functionality genuinely cannot work (a cart session, a login session, a security token), are exempt from consent requirements. The moment you add anything used for analytics, personalization beyond the immediate session, or advertising, you're back to needing consent for those specific cookies.

Conclusion

GDPR cookie consent isn't about adding a banner to check a compliance box, it's about making sure tracking scripts genuinely wait for a visitor's explicit, informed choice before they run. That distinction is what separates the plugins and code shown here from the "cookie notice" banners that still litter the web and do nothing legally meaningful.

For most sites juggling several third-party scripts, a plugin like CookieYes or Complianz is the pragmatic choice, handling script-blocking, categorization, and consent logging without you maintaining that logic yourself. If your tracking footprint is small and well understood, the functions.php approach in this guide gives you the same core guarantee, consent captured before tracking loads, without an added plugin dependency.

Whichever path you take, pair it with the rest of your site's privacy and security posture. A visitor who trusts your cookie banner deserves a site that's also been hardened against the more common threats covered in our guide on how to secure a WordPress website.

Tags :
Share :

Related Posts

Effortlessly Crafting Compelling WordPress Pages

Effortlessly Crafting Compelling WordPress Pages

As a website owner or content creator, having the ability to seamlessly add new pages to your WordPress site is crucial. Whether you're introducing a

Continue Reading
High Traffic Tips for WordPress Mastery 🚥

High Traffic Tips for WordPress Mastery 🚥

In our digital age, where online visibility is paramount, ensuring your WordPress site can handle surging traffic is crucial. Just like a finely-tune

Continue Reading
How Do I Change the WordPress Login URL?

How Do I Change the WordPress Login URL?

By default, every WordPress site's login page lives at the same predictable address: yoursite.com/wp-login.php (which also happens to redirect from

Continue Reading