Google Consent Mode v2 cookie consent plugin with session attribution preservation, custom script management, and gtag.js/GTM support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3.7 KiB
ATT Consent - Developer Context
What This Is
A WordPress plugin implementing Google Consent Mode v2 with session attribution preservation. It replaces paid CMv2 plugins (e.g., CookieYes) with a self-contained, distributable alternative.
Architecture
Core Flow
- Inline
<head>script (priority 1) - Sets consent defaults and captures attribution to sessionStorage. Must run before any Google tags. - Tracking script (priority 2) - Loads gtag.js or GTM. In Advanced mode, loads immediately. In Basic mode, deferred until consent.
- Footer - Banner HTML + enqueued
banner.jsandbanner.css.
Key Files
includes/class-frontend.php- Orchestrates the output order. Theoutput_consent_defaults()method generates the critical inline script.public/js/consent-manager.js- Core logic:AttConsent.update()replays attribution, sends consent signals, injects scripts, sets cookie. This is the public API.public/js/banner.js- UI only. CallsAttConsent.update()on button clicks.includes/class-admin.php- Admin settings with 5 tabs. Handles save viaadmin_post, scripts CRUD via AJAX.includes/class-scripts-manager.php- CRUD for custom JS snippets stored in{prefix}att_cc_scriptstable.
Settings
Single serialized option: att_consent_settings. Access via ATT_Consent::get_settings() which merges with defaults.
Custom Scripts Table
{prefix}att_cc_scripts (id, name, snippet, category, placement, status, priority, created_at, updated_at)
Scripts are passed to frontend JS via the inline config object, NOT rendered in PHP (they'd execute before consent). Injected into DOM by consent-manager.js after consent.
Consent Cookie
Name: att_cc_consent. Value: JSON {"functional":bool,"analytics":bool,"marketing":bool}. First-party, SameSite=Lax.
Attribution Storage
sessionStorage key att_cc_attr stores referrer, UTMs, GCLID/DCLID on first page of session. Key att_cc_consent_given tracks whether attribution has been replayed. Attribution is replayed via gtag('set') BEFORE gtag('consent','update') so GA4 session_start gets correct source.
Category-to-Signal Mapping
| Category | Google Signals |
|---|---|
| Necessary | security_storage (always granted) |
| Functional | functionality_storage, personalization_storage |
| Analytics | analytics_storage |
| Marketing | ad_storage, ad_user_data, ad_personalization |
WordPress Hooks
Filters: att_consent_settings_save, att_consent_banner_html
Actions: att_consent_before_banner, att_consent_after_banner
JS Event: att_consent_update (CustomEvent with detail: {functional, analytics, marketing})
Coding Standards
- WordPress PHPCS (WordPress-Extra)
- All admin inputs sanitized:
sanitize_text_field,sanitize_hex_color,absint,wp_kses_post - Nonce verification on all forms and AJAX
- Capability check:
manage_optionsfor all admin operations - Script snippets stored raw (admin-only input, intentionally executable)
- Frontend JS is vanilla - no jQuery dependency
- Text domain:
att-consent
Testing
Activate plugin, enter a GA4 Measurement ID in General settings, visit frontend. Verify:
window.dataLayercontains consent default withwait_for_update- Clicking Accept All fires
gtag('consent','update')with all granted - Cookie
att_cc_consentis set - Return visit: no banner shown, consent applied from cookie
- Attribution test: visit with
?utm_source=test, navigate without consenting, consent on page 2, check GA4 DebugView for correct source
Environment
- WordPress 6.8.3, Astra child theme
- Local Sites development environment
- WooCommerce + LearnPress site
- Previously used CookieYes (
cookie-law-infoplugin)