Skip to content

Region‐based consent rules

Konstantinos Pappas edited this page Nov 5, 2026 · 4 revisions

Caution

This feature will be included in version 2.0.0 of the Pressidium Cookie Consent plugin. It has not been released yet. The information provided here is subject to change.

On the “Geo Rules” tab, you can choose whether visitors from specific countries see the cookie consent in opt-in or opt-out mode.

Mode Behavior
Opt-in Scripts will run only after the user accepts their category (GDPR compliant)
Opt-out Scripts will run automatically unless the user opts out (it is generally not GDPR compliant)

Default consent mode

Select the consent mode for visitors who aren’t located in any of the declared regions, or whose country can’t be detected. It is set to Opt-in by default.

At the top of the tab, you’ll see a notice with the country detected for your own current request (e.g. GB). If you see a warning that no country could be detected, your server isn't providing country information (see Country detection below). In that case, region rules can’t be applied, and every visitor gets the default consent mode.

Opt-in and opt-out regions

  • Opt-in regions: Countries where users must explicitly consent before scripts run
  • Opt-out regions: Countries where scripts run automatically unless the user opts out

To add countries to a list, click the “Add Region” button, search for the countries you want, select them (or click “Select all”), and click “Add”. A country can only belong to one of the two lists.

For example, to use opt-in everywhere except the United States, you would:

  1. Set the default consent mode to Opt-in
  2. Add United States (US) to the opt-out regions

How it works

The consent mode is decided in the visitor’s browser, not when the page is rendered. That way, we serve the same HTML to every visitor, and the plugin works with full-page caching (e.g. server-side caches, caching plugins, CDNs).

flowchart TD
    pageLoads([Page loads]) --> hasRegions{Any regions added?}
    hasRegions -- No --> useDefault[Use default consent mode]
    hasRegions -- Yes --> hasConsent{Valid consent<br/>already given?}
    hasConsent -- Yes --> needsReconsent{Re-consent enabled<br/>and cookies changed?}
    needsReconsent -- No --> skipLookup([Skip lookup:<br/>consent mode not needed])
    needsReconsent -- Yes --> isCached
    hasConsent -- No --> isCached{Country already looked up<br/>this browser session?}
    isCached -- Yes --> matchRegion
    isCached -- No --> geoRequest["POST /wp-json/pressidium-cookie-consent/v1/geo"]
    geoRequest -- "Fails or takes > 1.5s" --> useDefault
    geoRequest -- Returns result --> matchRegion{Where is the<br/>visitor's country?}
    matchRegion -- In opt-in regions --> useOptIn[Use opt-in]
    matchRegion -- In opt-out regions --> useOptOut[Use opt-out]
    matchRegion -- "Neither, or not detected" --> useDefault
Loading

When a page loads, the plugin:

  1. Skips the lookup and uses the default consent mode if you haven’t added any regions
  2. Skips the lookup if the visitor has already given valid consent, since the consent mode no longer matters by then. If you’ve enabled the “Re-consent” option and your cookies have changed, the visitor’s country is looked up again.
  3. Otherwise, gets the visitor’s country from the POST /wp-json/pressidium-cookie-consent/v1/geo REST API endpoint
  4. Uses opt-in if the country is in your opt-in regions, opt-out if it’s in your opt-out regions, and the default consent mode otherwise

Note

The POST /wp-json/pressidium-cookie-consent/v1/geo endpoint uses POST instead of GET to avoid caching by server-side caches and CDNs, which could otherwise cause one visitor to receive another visitor’s country.

The result of the lookup is stored for the rest of the browser session, so the endpoint is called at most once per session. If the lookup fails or times out (i.e. takes longer than 1.5 seconds), the default consent mode is used.

Note

If you’re using a security plugin or firewall that restricts access to the WordPress REST API, make sure the POST /wp-json/pressidium-cookie-consent/v1/geo endpoint is reachable by anonymous visitors.

Country detection

The plugin reads the visitor’s country from the first of the following server variables that contains a valid two-letter country code:

  • MM_COUNTRY_CODE
  • GEOIP_COUNTRY_CODE
  • HTTP_CF_IPCOUNTRY (Cloudflare’s CF-IPCountry header)
  • HTTP_X_COUNTRY_CODE (X-Country-Code header)

If your site is behind Cloudflare with IP geolocation enabled, or your host adds one of these headers, region rules work without any extra setup.

Note

Cloudflare’s special XX (unknown) and T1 (Tor) codes are treated as “no country detected”.

Filters

If your host passes the country in a different header, add it with the pressidium_cookie_consent_geo_server_keys filter. Request headers appear as HTTP_ followed by the header name in uppercase, with hyphens replaced by underscores (e.g. X-Geo-Country → HTTP_X_GEO_COUNTRY).

add_filter( 'pressidium_cookie_consent_geo_server_keys', function ( $server_keys ) {
    // Check our custom header first
    array_unshift( $server_keys, 'HTTP_X_GEO_COUNTRY' );
    return $server_keys;
} );

To detect the country yourself (e.g. with your own GeoIP database or service), use the pressidium_cookie_consent_geo_country_code filter. Return a two-letter country code, or null if the country can’t be detected.

add_filter( 'pressidium_cookie_consent_geo_country_code', function ( $country_code, $ip_address ) {
    if ( $country_code !== null ) {
        // A country was already detected from the server variables
        return $country_code;
    }

    return my_geoip_lookup( $ip_address ); // e.g. 'DE'
}, 10, 2 );

The IP address passed to that filter defaults to $_SERVER['REMOTE_ADDR']. If your site is behind a reverse proxy or load balancer, you can change it with the pressidium_cookie_consent_geo_ip_address filter.

add_filter( 'pressidium_cookie_consent_geo_ip_address', function ( $ip_address ) {
    return $_SERVER['HTTP_X_REAL_IP'] ?? $ip_address;
} );

Clone this wiki locally