=== LandexHub Consent – Cookie Banner, GDPR & Google Consent Mode v2 ===
Contributors: landexhub
Tags: cookie-consent, cookie-banner, gdpr, consent-mode, cookies
Requires at least: 6.3
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 0.9.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Cookie banner for GDPR with Google Consent Mode v2, script gating, site diagnostics and consent logging. No cloud service required.

== Description ==

LandexHub Consent is a lightweight, configurable cookie consent banner (cookie bar) for WordPress. It sets the Google Consent Mode v2 default **before** the Google tags it loads, lets you gate third-party scripts behind consent, checks your front page for sources that load before the visitor decides, and records a privacy-minimal proof of consent — all stored in your own WordPress. No visitor IP address is stored in the consent log, and the plugin sends no telemetry and no data of its own anywhere. Google tags you choose to configure talk to Google, as described under External services.

**Features**

* Consent banner and preferences modal, responsive and accessible, with a live preview in the admin.
* Four categories — necessary, analytics, marketing, personalization — mapped to Google Consent Mode v2 signals.
* Google Consent Mode v2, **advanced by default**: measurement runs cookieless before consent and fully after. The `denied` default is printed early in `<head>`, before the GTM container or gtag.js set in this plugin. Switch to **basic** if the gtag.js measurement ID set in this plugin should not load at all until the visitor agrees. A GTM container always loads; what each tag inside it does before consent is set in GTM.
* Optional GTM / gtag.js loading — fill in your container or measurement ID (G-, AW- or DC-) and the plugin loads it right after its consent default.
* Script gating — mark any script (inline or external) with `type="text/plain"` and `data-consent-category` (an external one keeps its address in `data-src`), or gate an enqueued script with the `LandexHub_Consent::block_handle()` PHP helper. The plugin runs it once the visitor consents to that category.
* Site check — reads the HTML of your front page and lists the third-party scripts, embedded frames and known tracking pixels it recognises there, an estimate of who adds each one and whether consent governs it. Requests that scripts make later, other pages and the tags inside a GTM container are not checked. Each source that loads before consent comes with step-by-step instructions to gate it by hand.
* Google tag order check — warns when a tag is configured before the consent default (it would measure without consent) or when the same container is loaded twice.
* Services list — keep a list of the services your site uses with their consent category, and show it to visitors on your cookie policy page with the `[landexhub_consent_services]` shortcode or the "Services & cookies overview" block. A bundled catalog of 66 known services adds names, cookies and privacy policy links. Codes the site needs to work, such as payments, spam protection or pickup point maps, are listed apart as functional codes: they run without consent and are not reported as a problem.
* Consent integrations — publishes the visitor's decision through the WP Consent API standard for plugins that read it, and sends Google Consent Mode v2 signals that Google tags added by other plugins follow. Tested with Site Kit by Google (its own Consent Mode on or off) and MonsterInsights.
* Proof-of-consent log in your own database (no IP address in the records), with filters, CSV/JSON export and 30-day statistics. Each record carries a fingerprint of the bar texts its page was shown with; when that fingerprint is not known, the texts current at the time are recorded and the record is marked so. You choose how long records are kept (3 months to 5 years, or until you delete them).
* WordPress privacy tools integration (export/erase) and automatic cleanup of old records.
* Three-step setup on first run, settings import/export, consent reset and a diagnostic report.
* Admin translated into Czech, Slovak, Polish and German.
* Multisite supported.

**Privacy**

The plugin reports nothing about your site or your visitors to anyone. The consent log is written to a table in your own site, without IP addresses. Scripts you configure yourself (GTM, gtag.js) are loaded from Google.

Plugin author: LandexHub — [terms](https://landexhub.com/terms), [privacy policy](https://landexhub.com/privacy). LandexHub also makes a separate, optional add-on; this plugin does not need it.

**Source code**

Nothing in this plugin is minified, compressed or obfuscated. The JavaScript in `assets/js/` is compiled from TypeScript, and those TypeScript sources ship with the plugin in the `src/` folder together with the compiler configuration and build instructions (`src/README.md`). One command with the TypeScript compiler reproduces the shipped files byte for byte.

== External services ==

This plugin does not call home and sends no telemetry. Depending on what **you** configure, it talks to the following services:

**Google Tag Manager / Google tag (gtag.js)** — optional, disabled by default. If you enter your own GTM container ID or gtag.js measurement ID in the plugin settings, the plugin embeds the standard Google snippet, and every visitor's browser then loads the tag from `www.googletagmanager.com` (requests `gtm.js` or `gtag/js`). This is required for the measurement you configured to work. The plugin prints the Google Consent Mode v2 `denied` default before these tags, unless a developer turns that default off with the `landexhub_consent_emit_consent_default` filter. With a GTM container the plugin also prints Google's `<noscript>` frame right after the opening `<body>` tag (in themes that call `wp_body_open()`), as in Google's installation instructions: visitors without JavaScript then load `ns.html` from `www.googletagmanager.com`. Without JavaScript there is no consent bar and no Consent Mode default, so that request carries no consent state. What Google receives with those requests (IP address, user agent, page URL, consent state signals) is described in Google's documentation: [Google Terms of Service](https://policies.google.com/terms), [Google Privacy Policy](https://policies.google.com/privacy). If you leave the setting empty, nothing is loaded from Google by this plugin.

**Your own site (loopback)** — the site check fetches your own homepage over HTTP (a loopback request to your own server) to scan the HTML for third-party scripts and the Google tag order. No external service is involved.

There are no other remote requests: no telemetry, no fonts, no CDNs. Links to the LandexHub website open in a new tab and send nothing by themselves.

== Installation ==

1. Upload the plugin to `/wp-content/plugins/landexhub-consent`, or install it from Plugins → Add New.
2. Activate the plugin.
3. The three-step setup (appearance → measurement → site check) opens on first run; everything then lives under four tabs — Appearance, Services, Diagnostics, Advanced.
4. Gate third-party scripts with `type="text/plain"` and `data-consent-category` — the Services page shows what was found and how to gate each source (guide: https://docs.landexhub.com/consent/blocking-scripts).

== Frequently Asked Questions ==

= Does it store visitors' IP addresses? =

Not in the consent log. It is privacy-minimal: it stores a random consent identifier, the chosen categories, a timestamp, the page path and a fingerprint of the bar texts. To limit abuse of the recording, a request counter is kept under a salted hash of the visitor's IP address; it expires after 10 minutes.

= How do I handle a privacy request from an anonymous visitor? =

A record of an anonymous visitor has no IP address, e-mail or other identifier besides its random consent ID, so the log alone cannot tie it to a person (GDPR art. 11). A visitor can identify their own records with their consent ID, shown at the bottom of the consent settings dialog. Search the Consent log for that ID to show or export the records; an erase button deletes them. Logged-in users are covered by the standard WordPress Export/Erase Personal Data tools.

= Does it send data to third parties? =

The plugin itself sends nothing: no telemetry, and consent records stay in your WordPress. If you configure a GTM container or a Google measurement ID, your visitors' browsers load those Google tags and they communicate with Google — see External services. Scripts you gate run only after consent and then talk to their own providers.

= Does it support Google Consent Mode v2? =

Yes, in advanced mode (the default) or basic mode. In advanced mode Google tags load before consent and send cookieless signals until the visitor agrees; in basic mode the gtag.js ID set in this plugin loads only after consent. The `denied` default is printed before the GTM container or gtag.js set in this plugin. If you set your own consent default elsewhere, turn the plugin's default off with the `landexhub_consent_emit_consent_default` filter; it is not detected automatically.

= Can I block Google Analytics / Meta Pixel until consent? =

Mark the script tag with `type="text/plain" data-consent-category="marketing"`; for an external script also move its address from `src` to `data-src`. Or gate an enqueued script with the `LandexHub_Consent::block_handle( $handle, 'marketing' )` PHP helper. Google tags loaded through GTM or gtag.js follow Google Consent Mode, so they are usually not blocked; make sure the tags in your GTM container use consent settings — Custom HTML tags and non-Google tags in a container do not follow Consent Mode by themselves. Guide: [Blocking scripts](https://docs.landexhub.com/consent/blocking-scripts).

= Can visitors change or withdraw their consent later? =

Yes, always. By default a "Cookie settings" link is printed in the site footer; you can switch to a floating icon instead, place the `[landexhub_consent_settings]` shortcode or the "Cookie settings link" block anywhere, or call `LandexHubConsent.openSettings()` from your own link. A change updates Google Consent Mode and the WP Consent API immediately. One technical honesty note: a third-party script that already ran on the current page cannot be un-run — after a withdrawal it stays inactive from the next page load on.

= What does the site check do? =

It fetches your own front page (a request to your own server) and lists the third-party scripts, embedded frames and known tracking pixels it recognises in the HTML, who adds each of them and whether consent governs it. For every source that loads before consent it shows how to gate it by hand. It only sees the front page — a source that loads only on a subpage does not show up there.

= Does it pass consent to other plugins? =

Through two channels. When the free WP Consent API plugin is installed, the plugin publishes the visitor's decision on that shared standard, both in the browser and for `wp_has_consent()` in PHP, so plugins that read it can follow it. Google tags added by other plugins follow the Google Consent Mode v2 signals the plugin sends, as long as they load after its default.

Tested end to end (first visit, accept, reload, withdrawal, consent reset): Site Kit by Google with its own Consent Mode on (it then reads the WP Consent API) and off (its Google tag follows Consent Mode), and MonsterInsights with a manually entered GA4 ID (its tag follows Consent Mode; it does not read the WP Consent API). Other plugins were not tested; check them on your site.

= Can I show visitors a list of the services this site uses? =

Yes — put the `[landexhub_consent_services]` shortcode (or the "Services & cookies overview" block) on your cookie policy page. It renders a table of the services found on your front page and the ones in your services list, with consent category, known cookies and privacy policy links. It is generated technical data, not legal advice.

= Does the plugin make my site GDPR compliant? =

No plugin can do that on its own. LandexHub Consent provides the technical tools — consent banner, script gating, proof of consent, data export and erasure. Whether your site complies depends on how it is configured and on what it does; that responsibility stays with the site owner.

= Does it support IAB TCF? =

No. The plugin does not implement the IAB Transparency & Consent Framework (no TC string, no registered CMP ID). If your site serves personalised ads through Google AdSense or Ad Manager to visitors in the EEA/UK, Google requires a TCF-certified CMP — this plugin is not the right tool for that setup. For sites without ad networks (analytics, marketing pixels, embeds), Consent Mode v2 and script gating cover the consent flow.

== Screenshots ==

1. The consent banner with Accept / Reject and a preferences link.
2. The preferences modal with per-category toggles.
3. Appearance editor with live preview of the bar.
4. Services: everything the front page loads, where each one comes from and whether consent governs it.
5. Step-by-step guide to gate a source by hand.
6. Diagnostics: a verdict built from real checks, each with its evidence.
7. Consent log with filters, export and wording snapshots.

== Changelog ==

= 0.9.4 =
* Services shows where each source comes from (a plugin, the theme, a template file, page content) and a clearer service detail with what to do.
* Codes the site needs to work (payments, spam protection, pickup points) are listed apart as functional codes and are not reported as a problem.
* Larger catalog (66 services) and a more precise site check, including Google tags that start before the consent default.
* Google URL passthrough is now an opt-in setting; before, it was always on.
* New hooks for developers.

= 0.9.3 =
* GTM triggers on the consent event fire wherever the container is printed in the page.
* Google tags follow Google's installation snippets, including the GTM `<noscript>` frame.
* Services page fixes: "Verify the edit" returns to the service, no duplicate rows, necessary services are not reported as problems.

= 0.9.2 =
* Consent log retention is a setting: 3 months up to 5 years, or until you delete the records.
* The "Designed by LandexHub" credit link is off by default.
* Services list: save any source from the site check with a consent category for your cookie policy page.
* Stricter validation of settings and imports; the WordPress privacy tools export and erase a logged-in visitor's consent records.
* Multisite and WP Consent API fixes, and a more precise site check.

= 0.9.1 =
Initial release.

== Upgrade Notice ==

= 0.9.4 =
Functional codes (payments, spam protection, pickup points) are listed apart and never reported as a problem; Services shows where each source comes from; a larger catalog and a more precise site check. URL passthrough is now an opt-in setting.

= 0.9.3 =
GTM triggers on the consent event fire wherever the container is printed in the page. Fixes in the Services page: "Verify the edit" returns to the service, no duplicate rows for inline sources, necessary services are not reported as problems.

= 0.9.2 =
Configurable consent log retention, opt-in credit link and stricter settings validation.
