Can I put a consent link in my footer?
Yes. Add a Shortcode block to your site-wide footer containing [faz_cookie_settings type="link" text="Cookie preferences"] . The link uses your theme’s styling. Omit type="link" for the existing banner-coloured button. Both support a custom text and additional CSS class .
To replace the floating widget, put the link on every page and disable Banner → Advanced → Show revisit consent widget . Jurisdiction routing may lock that widget on; in that case both controls remain available. The shortcode needs the banner runtime and does not work on pages excluded from the banner. Standard navigation menu labels do not execute shortcodes; custom HTML can use <a href="#faz-consent" data-faz-open-preferences="1" aria-haspopup="dialog">Cookie preferences</a> .
Do scheduled scans require WP-CLI?
No. A hosting cron that calls WordPress’s wp-cron.php runs the plugin’s scheduled events too. If your host already provides that job, do not add a duplicate. System Status → Cron Jobs includes a cPanel example and explains how to check the next scheduled times.
Why does the dashboard show — for pageviews?
Pageview and banner interaction metrics show -- when pageview tracking is disabled. This means unavailable, rather than zero visits. Consent logging is a separate setting and can remain enabled.
Does this plugin require a cloud account or subscription?
No required cloud account or subscription is needed. Core consent features run locally, while some optional refresh/download features can contact documented third-party services such as GitHub, IAB Europe, MaxMind, or AMP infrastructure.
Is it really free? What’s the catch?
It’s free and open source (GPL-3.0). There are no premium upgrades, no feature gates, and no upsells. The plugin is based on the GPL-licensed CookieYes v3.4.0 codebase, with cloud dependencies removed and all included features running locally.
Is it compatible with Google Consent Mode v2?
Yes. The plugin sends all 7 consent signals ( ad_storage , analytics_storage , ad_user_data , ad_personalization , functionality_storage , personalization_storage , security_storage ) and supports Google Additional Consent Mode (GACM) for ad technology providers.
Does the banner block cookies before consent?
Yes. Known third-party scripts are blocked automatically. To gate one of your own, give it a non-executable type and name the category it belongs to:
<script type="text/plain" data-faz-category="analytics">/* your code */</script>
Both parts are required. The type is what stops the browser from running it before consent; data-faz-category is what the plugin looks for when it runs it afterwards. A script with only the type never runs at all — including after consent — and a script with only the attribute runs immediately, before any consent is given.
The same pair works for iframes, images and stylesheets using data-faz-src or data-faz-href in place of the real attribute.
Once consent is granted the plugin runs the script itself, on that page and on every later page load. You do not need to listen for fazcookie_consent_update to start it; that event is for your own code that has nothing to do with these tags.
How does the cookie scanner work?
Go to FAZ Cookie > Cookies and click Scan Site . The scanner runs in your browser using iframes, crawling your site’s pages to detect all cookies. Choose from quick scan (10 pages), standard (100), deep (1000), or full scan. No external service involved.
Can I log consent for GDPR accountability?
Yes. Every consent action (accept, reject, customize) is recorded in a local database table with timestamp, consent ID, categories chosen, anonymized IP, and page URL. Export to CSV anytime from the Consent Logs page.
Does it support multiple languages?
Yes. The Languages page lets you select from 180+ available languages. Each banner you create carries its own translations for every language you enable — the banner text (title, description, button labels) is stored per-language inside the banner row, and the language displayed to the visitor is resolved client-side from navigator.languages . WPML / Polylang URL-based language switching is auto-detected and always cache-safe.
Does multi-banner mean one banner per language?
No — multi-banner routing is per visitor country (e.g. GDPR vs CCPA, EU vs US), not per language. Each banner row carries its OWN multilingual content: title, description and button labels translated for every language you support. The visitor’s country selects the banner; the visitor’s browser language then selects which translated strings to render inside that banner. So an install with one EU-targeted GDPR banner (carrying English + Italian + German + French translations) and one US-targeted CCPA banner (carrying English + Spanish translations) needs only TWO banner rows, not eight. See the “Multi-banner geo-routing vs multilingual content” section in the Description for the full architecture.
Can users change their consent after accepting?
Yes. A floating revisit widget appears on every page, letting visitors reopen the preference center and change their choices at any time.
Is the banner accessible?
Yes. The banner supports full keyboard navigation (Tab, Enter, Escape), proper ARIA labels, and is responsive down to 375px viewports. Buttons have equal visual prominence to avoid dark patterns.
Does it work with caching plugins?
Yes. See the Cache Plugin Compatibility section below for the verified plugins, emitted cache-control signals, automatic FlyingPress handling and known CDN limitations.
Short answer
Yes. The consent banner is rendered via JavaScript from a cached template, so it works with all major caching plugins (WP Super Cache, W3 Total Cache, LiteSpeed Cache, etc.).
Does the plugin send any data home or collect telemetry?
No. The plugin contains no telemetry, no analytics beacon, and no “phone home”. Dashboard numbers are computed locally from your own wp_faz_pageviews and wp_faz_consent_logs tables. Every outbound request that can happen is documented in the “External services” section and is gated behind an explicit admin action.
Where is the source of the bundled minified JavaScript?
The minified files we ship are frontend/js/script.min.js , frontend/js/gcm.min.js , frontend/js/tcf-cmp.min.js and frontend/js/a11y.min.js . The full, unminified sources live next to each one as script.js , gcm.js , tcf-cmp.js and a11y.js , and the build command npm run build:min rebuilds them all with terser . No obfuscation is used.
Does uninstalling the plugin remove my data?
By default, no — your consent logs, banner configuration and categories stay in the database so you can reinstall without losing work. To wipe everything on uninstall, enable Settings → General → Remove all data on uninstall or define FAZ_REMOVE_ALL_DATA as true in wp-config.php before deleting the plugin.
Does the plugin include a CCPA “Do Not Sell” opt-out form?
Yes. Place [faz_do_not_sell] on any page (e.g. your Privacy Policy) to show a California Consumer Privacy Act opt-out form. When a visitor submits the form, the opt-out is logged in the local consent table with a hashed IP address, a long-lived cookie is set so the visitor sees a confirmation on subsequent visits, and the site admin receives a notification email. Optional attributes: title (heading text) and button (submit label). No external service is involved.
Does the plugin include a GDPR Data Subject Access Request (DSAR) form?
Yes. Place [faz_dsar_form] on any page to show a GDPR-compliant request form covering six rights: Access (Art. 15), Erasure (Art. 17), Data Portability (Art. 20), Rectification (Art. 16), Restriction (Art. 18), and the Right to Object (Art. 21). On submission, the request is stored as a private post in the WordPress database (so it survives email failures), a notification is sent to the admin with a direct link to the record, and a confirmation is sent to the requester. The form includes a honeypot field, a signed dwell-time stamp, an optional proof of work and nonce verification to block spam bots; the proof of work and the dwell stamp only charge clients that run the form’s JavaScript and never reject a client that omits them (fail-open by design), so the cumulative daily ceilings are the control that actually stops a spam chain. Optional attributes: button (submit label).
My site is behind Cloudflare or a reverse proxy. Are the data request form’s limits still per visitor?
They need to be, and since 1.34.1 the plugin resolves the visitor’s address on its own for the one case it can verify by itself: a request arriving from Cloudflare’s published edge ranges, where CF-Connecting-IP is read, and only there, because Cloudflare writes that header itself. Every other topology is resolved once you declare it, one line each.
For another CDN, add its published edge ranges and every per-visitor key in the plugin follows. A peer matched that way is read through faz_proxy_forwarded_header , which defaults to HTTP_X_FORWARDED_FOR and is read from the right-hand end of the chain, so for an edge that appends to X-Forwarded-For the range is all you need:
add_filter( 'faz_trusted_proxy_cidrs', function ( $cidrs ) { return array_merge( $cidrs, array( '203.0.113.0/24' ) ); } );
If that edge overwrites a header of its own instead, name it as well — the range trusts the peer, this filter says what to read:
add_filter( 'faz_proxy_forwarded_header', function () { return 'HTTP_TRUE_CLIENT_IP'; } );
For a reverse proxy on the same host, name the header it writes. Nothing is read from a loopback peer until you do: faz_loopback_proxy_header is unset by default, so an unconfigured site keeps using the connection’s own address and the per-connection limit is skipped rather than shared. Use whichever line your nginx config actually contains — proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; means HTTP_X_FORWARDED_FOR , proxy_set_header X-Real-IP $remote_addr; means HTTP_X_REAL_IP :
add_filter( 'faz_loopback_proxy_header', function () { return