Skip to Content
PluginsLW Cookie

LW Cookie

GDPR-compliant cookie consent banner for WordPress - minimal footprint, full compliance.

Overview

Requires WordPress6.0+
Requires PHP8.1+
Tested up to6.7
LicenseGPL-2.0-or-later
GitHublwplugins/lw-cookie 

Installation

composer require lwplugins/lw-cookie

Or upload the lw-cookie folder to /wp-content/plugins/ and activate through the Plugins menu.

Features

GDPR Compliance

  • Opt-in by default - all optional categories are OFF until user consents
  • Granular category selection (Necessary, Functional, Analytics, Marketing)
  • Consent logging with timestamp for compliance proof
  • Policy version tracking - automatic re-consent on policy changes
  • Anonymized IP logging (GDPR-compliant)
  • Customizable position (top, bottom, modal)
  • Customizable layout (full-width bar, floating box)
  • Customizable colors and border radius
  • Accept All / Reject All / Customize buttons
  • Floating button for easy access to change preferences

Script Blocking

  • Automatic blocking of known tracking scripts until consent
  • Supports Google Analytics, Facebook Pixel, Hotjar, and more
  • Scripts unblock dynamically when consent is given
  • Client-side blocking architecture - works with any page cache plugin
  • Built-in support for Google Consent Mode v2
  • Required for Google Ads and Analytics in the EU
  • Automatic consent signal updates
  • Loads before any tracking scripts (-PHP_INT_MAX priority)
  • EEA region-specific defaults

Meta Pixel (Facebook) Support

  • Automatic fbq('consent', 'revoke/grant') API calls
  • Works with existing Facebook Pixel implementations

Third-Party Plugin Integration

  • dataLayer.push events for GTM triggers (lw_cookie_consent_update)
  • WordPress filters for other plugins to query consent state
  • Script blocking override filter for plugin compatibility
  • Server-side cookie scanner detects all cookies including HttpOnly
  • Integration with LW Plugins Cookie Database API (2000+ cookies)
  • Automatic cookie enrichment with provider, purpose, and duration
  • Multi-page scanning (home, WooCommerce cart/checkout, posts)
CategoryDescriptionDefault
NecessaryEssential for website functionAlways enabled
FunctionalEnhanced functionality and personalizationOff until consent
AnalyticsVisitor analytics and statisticsOff until consent
MarketingAdvertising and remarketingOff until consent

Settings

Configure under LW Plugins > Cookie. The settings page uses a tabbed interface:

TabDescription
GeneralEnable/disable, policy version, consent mode
AppearanceColors, position, layout, border radius
TextsCustomize all labels and messages
CategoriesCookie category descriptions
DeclarationManage declared cookies

General Settings

Option: enabled | Default: true

Enables or disables the cookie consent banner on the frontend. When disabled, no banner will be shown and no scripts will be blocked.

Privacy Policy Page

Option: privacy_policy_page | Default: 0 (none)

Select the page containing your privacy policy. This page will be linked in the cookie banner, allowing users to review your privacy practices before making a consent decision.

Policy Version

Option: policy_version | Default: 1.0

The current version of your cookie/privacy policy. When you update this version number, all existing consents become invalid and users will be prompted to consent again.

Best Practice: Increment this version whenever you:

  • Add new cookie categories
  • Change how cookies are used
  • Update your privacy policy significantly

Appearance Settings

Option: banner_position | Default: bottom

ValueDescription
bottomFixed bar at the bottom of the viewport
topFixed bar at the top of the viewport
modalCentered modal overlay

Option: banner_layout | Default: bar

ValueDescription
barHorizontal bar spanning the viewport width
boxCompact box in the corner

Primary Color

Option: primary_color | Default: #2271b1

The primary color used for buttons (Accept All, Save Preferences). Accepts any valid CSS color value.

Text Color

Option: text_color | Default: #1d2327

The color used for banner text content.

Background Color

Option: background_color | Default: #ffffff

The background color of the cookie banner and preferences modal.

Border Radius

Option: border_radius | Default: 4

Border radius in pixels for buttons and the banner container. Set to 0 for sharp corners.

Categories Settings

LW Cookie uses four cookie categories as recommended by GDPR guidelines:

Necessary (Required)

Always enabled and cannot be disabled by users. These cookies are essential for basic website functionality.

Examples: Session cookies, shopping cart cookies, security cookies (CSRF tokens), cookie consent preferences.

Functional

Options: cat_functional_name (default: “Functional”), cat_functional_desc

Cookies that enhance website functionality and personalization but are not strictly necessary.

Examples: Language preferences, region/timezone settings, user interface customization, recently viewed items.

Analytics

Options: cat_analytics_name (default: “Analytics”), cat_analytics_desc

Cookies used to collect information about how visitors use the website.

Examples: Google Analytics, Matomo/Piwik, Hotjar, Microsoft Clarity.

Marketing

Options: cat_marketing_name (default: “Marketing”), cat_marketing_desc

Cookies used for advertising and tracking across websites.

Examples: Google Ads, Facebook Pixel, LinkedIn Insight Tag, retargeting cookies.

Texts Settings

All text displayed in the cookie banner can be customized:

OptionDefaultDescription
banner_titleWe value your privacyHeading at the top of the cookie banner
banner_messageWe use cookies to enhance your browsing experience and analyze our traffic.Main message explaining why cookies are used
btn_accept_allAccept AllAccepts all cookie categories
btn_reject_allReject AllRejects all optional categories
btn_customizeCustomizeOpens the preferences modal
btn_saveSave PreferencesSaves custom category selections

Advanced Settings

Option: consent_duration | Default: 365 (days)

How long the consent cookie is stored. After this period, users will be prompted to consent again.

GDPR Recommendation: Maximum 12 months (365 days).

Script Blocking

Option: script_blocking | Default: true

When enabled, known tracking scripts are automatically blocked until the user provides consent for the relevant category.

Blocked Scripts Include:

  • Google Analytics (analytics category)
  • Google Tag Manager (analytics category)
  • Facebook Pixel (marketing category)
  • Hotjar (analytics category)
  • LinkedIn Insight (marketing category)
  • Twitter/X Pixel (marketing category)
  • TikTok Pixel (marketing category)
  • Pinterest Tag (marketing category)
  • Snapchat Pixel (marketing category)

Option: gcm_enabled | Default: false

Enables Google Consent Mode v2 integration. When enabled, consent signals are automatically sent to Google services.

Show Floating Button

Option: show_floating_button | Default: true

Shows a small floating button allowing users to re-open the cookie preferences modal after they’ve made their initial choice.

Floating Button Position

Option: floating_button_pos | Default: bottom-left

ValueDescription
bottom-leftBottom left corner
bottom-rightBottom right corner

Admin Management

Navigate to LW Plugins > Cookie > Cookies to declare all cookies used on your website.

For each cookie, you can specify:

  • Cookie Name - The actual cookie name (e.g., _ga, _fbp)
  • Provider - Who sets this cookie (e.g., Google Analytics, Facebook)
  • Purpose - What the cookie is used for
  • Duration - How long the cookie is stored (e.g., 1 year, Session)
  • Category - Which consent category it belongs to
  • Type - Session (deleted when browser closes) or Persistent

Use the “Add Common Cookies” button to quickly add commonly used cookies (WordPress, Google Analytics, Facebook Pixel).

Shortcode

Display your cookie declaration on any page using the shortcode:

[lw_cookie_declaration]

Attributes:

AttributeDefaultDescription
class(empty)Additional CSS class for styling

Example:

[lw_cookie_declaration class="my-custom-table"]

The shortcode displays:

  • Cookies grouped by category
  • Category names and descriptions
  • Full cookie details (name, provider, purpose, duration, type)
  • “Manage Cookie Preferences” button
  • Responsive table design (mobile-friendly)

Shortcodes

ShortcodeDescription
[lw_cookie_declaration]Display cookie declaration table on any page

WP-CLI Commands

LW Cookie provides comprehensive WP-CLI support for managing settings and consent data from the command line.

Available Commands

CommandDescription
wp lw-cookie settings listList all settings with current values
wp lw-cookie settings get <key>Get a specific setting value
wp lw-cookie settings set <key> <value>Set a specific setting value
wp lw-cookie settings resetReset all settings to defaults
wp lw-cookie keysShow all available setting keys
wp lw-cookie statsDisplay consent statistics
wp lw-cookie exportExport consent logs
wp lw-cookie clear-logsClear consent logs

Settings Management

List All Settings

# Table format (default) wp lw-cookie settings list # JSON format wp lw-cookie settings list --format=json # YAML format wp lw-cookie settings list --format=yaml

Get a Setting

wp lw-cookie settings get enabled # Output: true wp lw-cookie settings get primary_color # Output: #2271b1

Set a Setting

# Enable/disable banner wp lw-cookie settings set enabled true wp lw-cookie settings set enabled false # Change colors wp lw-cookie settings set primary_color "#ff6600" wp lw-cookie settings set background_color "#f5f5f5" # Change texts wp lw-cookie settings set banner_title "Cookie Settings" wp lw-cookie settings set btn_accept_all "Accept Cookies" # Change position wp lw-cookie settings set banner_position top wp lw-cookie settings set banner_position modal # Enable Google Consent Mode wp lw-cookie settings set gcm_enabled true # Set consent duration (days) wp lw-cookie settings set consent_duration 180

Reset Settings

wp lw-cookie settings reset # Resets all settings to default values

View Available Keys

wp lw-cookie keys # Output: # +------------------------+-------------------------------------+---------+ # | key | description | default | # +------------------------+-------------------------------------+---------+ # | enabled | Enable/disable cookie banner | true | # | privacy_policy_page | Privacy policy page ID | 0 | # | policy_version | Current policy version | 1.0 | # | banner_position | Banner position (bottom, top, modal)| bottom | # | ... | ... | ... | # +------------------------+-------------------------------------+---------+
# Default: last 30 days wp lw-cookie stats # Custom time period wp lw-cookie stats --days=7 wp lw-cookie stats --days=90 # JSON output wp lw-cookie stats --format=json

Example output:

+--------------------------------+-------+ | metric | value | +--------------------------------+-------+ | Total consents (all time) | 1543 | | Consents (last 30 days) | 234 | | Accept All (last 30 days) | 156 | | Reject All (last 30 days) | 45 | | Customize (last 30 days) | 33 | | Accept All rate | 66.7% | | Reject All rate | 19.2% | +--------------------------------+-------+
# Export to table (default) wp lw-cookie export # Export to CSV file wp lw-cookie export --format=csv > consents.csv # Export to JSON wp lw-cookie export --format=json --limit=1000 # Export last 30 days only wp lw-cookie export --days=30 --format=csv
# Delete all logs (requires confirmation) wp lw-cookie clear-logs # Skip confirmation wp lw-cookie clear-logs --yes # Delete only old logs wp lw-cookie clear-logs --older-than=365 --yes

GDPR Data Requests (CLI)

# Search by consent ID wp lw-cookie consent --consent-id=abc123-def456-xyz789 # Search by IP address (will be hashed internally) wp lw-cookie consent --ip=192.168.1.100 # Export to JSON wp lw-cookie consent --ip=192.168.1.100 --format=json
# Find and delete records wp lw-cookie consent --consent-id=abc123-def456 --delete # With confirmation skip wp lw-cookie consent --ip=192.168.1.100 --delete --yes

Automation Examples

Backup Settings Before Update

# Export current settings wp lw-cookie settings list --format=json > lw-cookie-backup.json

Deploy Settings Across Environments

# On staging/production wp lw-cookie settings set enabled true wp lw-cookie settings set gcm_enabled true wp lw-cookie settings set policy_version "2.0" wp lw-cookie settings set primary_color "#0066cc"

Scheduled Log Cleanup (Cron)

# Add to crontab: delete logs older than 1 year 0 0 1 * * cd /var/www/html && wp lw-cookie clear-logs --older-than=365 --yes

Monthly Statistics Report

#!/bin/bash echo "=== LW Cookie Monthly Report ===" echo "Date: $(date)" wp lw-cookie stats --days=30 --format=table

JavaScript API

LW Cookie exposes a global LWCookie object for programmatic access:

Methods

// Accept all cookies LWCookie.acceptAll(); // Reject all optional cookies LWCookie.rejectAll(); // Open the preferences modal LWCookie.openPreferences(); // Get current consent state const consent = LWCookie.getConsent(); // Returns: { necessary: true, functional: false, analytics: false, marketing: false } // Check if a specific category is allowed if (LWCookie.isAllowed('analytics')) { // Load analytics scripts }

Events

Listen for consent changes:

window.addEventListener('lwCookieConsent', function(e) { console.log('Consent updated:', e.detail.categories); console.log('Action:', e.detail.action); // 'accept_all', 'reject_all', or 'customize' if (e.detail.categories.analytics) { // User accepted analytics cookies } });

Conditional Script Loading

You can use the API to conditionally load scripts:

document.addEventListener('DOMContentLoaded', function() { if (LWCookie.isAllowed('analytics')) { // Load Google Analytics var script = document.createElement('script'); script.src = 'https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID'; document.head.appendChild(script); } });

When Google Consent Mode is enabled, LW Cookie automatically manages the following consent signals:

SignalCookie Category
analytics_storageAnalytics
ad_storageMarketing
ad_user_dataMarketing
ad_personalizationMarketing

Default State

Before user consent, all signals default to denied:

gtag('consent', 'default', { 'analytics_storage': 'denied', 'ad_storage': 'denied', 'ad_user_data': 'denied', 'ad_personalization': 'denied' });

When users provide consent, signals are updated accordingly:

gtag('consent', 'update', { 'analytics_storage': 'granted', // if analytics accepted 'ad_storage': 'granted', // if marketing accepted 'ad_user_data': 'granted', // if marketing accepted 'ad_personalization': 'granted' // if marketing accepted });

Script Blocking

How It Works

When script blocking is enabled, the plugin:

  1. Scans all <script> tags during page load
  2. Identifies known tracking scripts by their URL patterns
  3. Blocks scripts that require consent for categories the user hasn’t accepted
  4. Automatically unblocks and loads scripts when consent is granted

Blocked Script Patterns

PatternCategory
google-analytics.comAnalytics
googletagmanager.comAnalytics
facebook.netMarketing
connect.facebook.netMarketing
hotjar.comAnalytics
clarity.msAnalytics
linkedin.com/insightMarketing
ads.twitter.comMarketing
tiktok.comMarketing
pintrkMarketing
snap.licdn.comMarketing

Custom Script Blocking

For scripts not automatically detected, use the type attribute:

<!-- Block until analytics consent --> <script type="text/plain" data-consent-category="analytics" data-src="https://example.com/analytics.js"></script> <!-- Block until marketing consent --> <script type="text/plain" data-consent-category="marketing" data-src="https://example.com/pixel.js"></script>

Database & GDPR Compliance

All consent actions are logged to the {prefix}lw_cookie_consents table:

ColumnDescription
idAuto-increment ID
consent_idUUID v4 identifier
ip_hashSHA-256 hashed IP (anonymized)
categoriesJSON object of consent choices
policy_versionPolicy version at time of consent
action_typeaccept_all, reject_all, or customize
user_agentBrowser user agent string
created_atTimestamp of consent

Consent is stored in a cookie named lw_cookie_consent containing base64-encoded JSON:

{ "id": "uuid-v4", "version": "1.0", "timestamp": 1706745600, "categories": { "necessary": true, "functional": false, "analytics": false, "marketing": false } }

GDPR Compliance Features

  • Opt-in by default: All optional categories are OFF by default
  • Granular control: Users can select individual categories
  • Easy withdrawal: Floating button allows changing preferences anytime
  • Consent proof: All consents are logged with timestamps
  • Re-consent: Policy version changes trigger new consent requests
  • IP anonymization: IP addresses are hashed, not stored in plain text
  • Data retention: Consent logs can be purged based on your retention policy

Data Export

To export consent data for a specific user (GDPR data request):

SELECT * FROM wp_lw_cookie_consents WHERE consent_id = 'user-consent-uuid';

Data Deletion

To delete consent data (GDPR erasure request):

DELETE FROM wp_lw_cookie_consents WHERE consent_id = 'user-consent-uuid';

Hooks & Filters

Filters

// Get consent categories and their states $categories = apply_filters( 'lw_cookie_consent_categories', [] ); // Returns: ['necessary' => true, 'analytics' => false, 'marketing' => true] // Check if user has given any consent $has_consent = apply_filters( 'lw_cookie_has_consent', false ); // Check if a specific category is allowed $analytics_ok = apply_filters( 'lw_cookie_is_category_allowed', false, 'analytics' ); // Get current consent ID $consent_id = apply_filters( 'lw_cookie_consent_id', null );

Example: conditional script loading

// Load analytics only if user consented if ( apply_filters( 'lw_cookie_is_category_allowed', false, 'analytics' ) ) { wp_enqueue_script( 'my-analytics', '...' ); }

REST API

LW Cookie uses REST API endpoints for consent logging (replaces admin-ajax for cache compatibility).

AI Abilities

When used with LW Site Manager, the following abilities are available for AI agents. All abilities are registered under the cookie category and require manage_options capability.

lw-cookie/get-options (readonly)

Get all LW Cookie consent settings.

Input: none

Output:

{ "success": true, "options": { "enabled": true, "banner_position": "bottom", "banner_layout": "bar", "primary_color": "#d4a017", "consent_duration": 365, "script_blocking": true, "gcm_enabled": false } }

lw-cookie/set-options (write)

Update one or more LW Cookie settings. Only the provided keys are changed.

Input:

{ "options": { "enabled": true, "banner_position": "top", "primary_color": "#2271b1", "consent_duration": 180 } }

Writable keys: enabled, privacy_policy_page, policy_version, banner_position, banner_layout, primary_color, text_color, background_color, border_radius, cat_functional_name, cat_functional_desc, cat_analytics_name, cat_analytics_desc, cat_marketing_name, cat_marketing_desc, banner_title, banner_message, btn_accept_all, btn_reject_all, btn_customize, btn_save, consent_duration, script_blocking, content_blocking, gcm_enabled, show_floating_button, floating_button_pos

Output:

{ "success": true, "message": "3 option(s) updated.", "updated": ["banner_position", "primary_color", "consent_duration"] }

Get consent logging statistics from the database, grouped by action type.

Input:

FieldTypeDefaultDescription
daysinteger30Number of past days to include

Output:

{ "success": true, "stats": { "accept_all": 142, "reject_all": 38, "customize": 21 }, "total": 201, "period_days": 30 }

lw-cookie/scan-cookies (write)

Trigger an HTTP header pre-scan across site URLs. Sends HEAD requests to home, pages, posts, and WooCommerce URLs to detect cookies set via Set-Cookie headers. Results are merged into the persistent scanner storage.

Input: none

Output:

{ "success": true, "cookies": ["_ga", "wc_cart_hash", "wordpress_sec"], "domains": [], "urls_count": 12 }

Note: This is a write ability because it performs HTTP requests and modifies stored scanner data. For a full browser-based scan (JS cookies, external domains, fonts), use the admin scanner UI.

Troubleshooting

  1. Check if the plugin is enabled in settings
  2. Clear any caching plugins
  3. Check browser console for JavaScript errors
  4. Verify the consent cookie doesn’t already exist

Scripts Still Loading

  1. Ensure Script Blocking is enabled
  2. Check if the script URL matches known patterns
  3. For custom scripts, add the appropriate data attributes
  4. Clear server-side cache after changing settings
  1. Enable GCM in Advanced settings
  2. Ensure gtag is loaded before LW Cookie
  3. Verify consent signals in browser console:
    console.log(window.dataLayer);

FAQ

Is this plugin GDPR compliant?

This plugin provides the technical framework for GDPR-compliant cookie consent. However, compliance also depends on how you configure it and your overall privacy practices. Ensure you have a proper privacy policy and only use cookies as described.

How do I customize the banner appearance?

Go to LW Plugins > Cookie > Appearance to customize colors, position, and layout.

What scripts are automatically blocked?

The plugin automatically detects and blocks known tracking scripts including Google Analytics, Google Tag Manager, Facebook Pixel, Hotjar, LinkedIn Insight Tag, Twitter Pixel, TikTok Pixel, Microsoft Clarity, and more.

How does Google Consent Mode work?

When enabled, the plugin sets Google Consent Mode v2 signals based on user consent. This is required for Google Ads and Analytics to function properly in the EU.

Can users change their consent after accepting?

Yes. If you enable the floating button in settings, users can click it anytime to open the preferences modal and change their choices.

Is consent logged?

Yes. All consent actions are logged to the database with a unique consent ID, anonymized IP hash, categories selected, policy version, and timestamp.

What happens when I update my privacy policy?

Change the “Policy Version” setting in the General tab. Users will be asked for consent again on their next visit.

Does it work with page cache plugins?

Yes. Since v1.6.0, LW Cookie uses a client-side blocking architecture that works with any full-page cache plugin (WP Rocket, LiteSpeed Cache, Cloudflare, etc.).