WordPress

The Zero Ad Network plugin announces your Publisher ID, recognises subscribers, and cleans up pages through popular ad, consent, popup and membership plugins.

In short

  • You need: WordPress 4.9 or newer, PHP 7.2 or newer with the Sodium extension, and your Publisher ID.
  • You do: install the plugin, paste your ID, choose any paid content to include, and make subscriber requests bypass your page cache.
  • Done when: a test subscriber sees clean pages and included content, and everyone else sees your normal website.

Your Publisher ID

This is an example Publisher ID. Replace it with your own before using it.

zapub_7Fq2xR9nKd3wV8mB4tL6yH1c

You can also copy it from Websites & creators.

1. Install and configure

  1. In WordPress, open Plugins → Add New Plugin. Search for Zero Ad Network, then install and activate it. You can also download it from WordPress.org, and use Upload Plugin.
  2. Open Zero Ad Network → Settings.
  3. Paste your Publisher ID, and select Enable Plugin.
  4. Leave Publisher Header Method set to HTTP Response Header. Choose HTML Meta Tag only if your hosting requires it.
  5. Save your settings.

The plugin takes your allowed hostnames from your WordPress Address and Site Address settings. These must match the public domains you serve.

2. Include paid content

Skip this step if you don't sell access.

  1. Edit a post or page you want subscribers to read.
  2. In the Freedom access box, check Include this content with Freedom.
  3. Save. Repeat for each post or page.

Offer your base subscription content, or a custom selection of paid content. Anything you don't select keeps its current restrictions.

3. Set up page caching

Page caches can serve pages before WordPress runs, so the plugin never sees the subscriber. Configure every cache so requests that carry Better-Web-Token bypass it and reach WordPress. See Page caches and CDNs below.

Then clear all page caches.

4. Check it works

  1. Visit a public page. Confirm it includes Better-Web-Publisher, as a response header or meta tag.
  2. Once your website appears in your dashboard, open its page and select Test in your browser.
  3. Visit pages with ads, cookie banners and popups. They should be gone.
  4. Open included paid content. It should open. Unselected, private, draft and password-protected content should stay protected.
  5. Open the same URLs without the extension. Your normal website should still work.

What changes for subscribers

On normal front-end pages, a verified subscriber gets every supported integration at once:

  • Ads and known non-essential tracking scripts are removed.
  • Cookie consent banners and marketing popups are removed or hidden.
  • Posts and pages you included open through the supported membership plugins.

These stay the same:

  • Unselected content, higher tiers, private posts, drafts and password-protected posts keep their restrictions.
  • The plugin doesn't create purchases, website memberships or admin permissions.
  • WordPress admin, AJAX, REST API and JSON responses are never changed.

Visitors with a missing or invalid token get your normal website.

The plugin can't cover every theme or custom ad placement. Check real pages, including protected posts and scripts your theme loads. See the supported plugins reference.

Troubleshooting

Your website isn't detected. Check that the plugin is enabled, the Publisher ID is correct, and old cached pages are cleared.

Subscribers still see ads or a paywall. First, check that their requests reach WordPress with Better-Web-Token. A page cache or CDN is the usual cause. Then check the plugin integration for that ad or paywall.

Page caches and CDNs

A page cache can serve HTML before WordPress runs, so the plugin can't check the token. Configure every caching layer to skip both cache reads and writes when a request includes Better-Web-Token, and to forward that header to WordPress.

Once the plugin runs, it takes care of the response:

  • Token requests get Cache-Control: private, no-store, no-cache, must-revalidate, max-age=0, plus CDN and LiteSpeed no-store signals and DONOTCACHEPAGE.
  • Public responses stay cacheable, and vary on Better-Web-Token.
  • It creates no subscriber cookies or subscriber cache entries. A zeroad_variant cookie or X-ZeroAd-Variant header never grants access.

For Nginx, Varnish and Cloudflare rules, and the full cache test, see Page caching and CDNs.

WordPress and server caches

PHP page caches can load through advanced-cache.php, before regular plugins run. If your website already defines WP_CACHE, replace that definition in wp-config.php with this:

$freedomTokenRequest = array_key_exists('HTTP_BETTER_WEB_TOKEN', $_SERVER);

define('WP_CACHE', !$freedomTokenRequest);

if ($freedomTokenRequest && !defined('DONOTCACHEPAGE')) {
    define('DONOTCACHEPAGE', true);
}

Don't add a second WP_CACHE definition. This bypasses the PHP drop-in only. It doesn't bypass a CDN, or a web-server rule that serves cached HTML directly. WordPress loads the drop-in early.

Cache What to configure
WP Super Cache Use PHP/Simple delivery with the bypass above. Expert (rewrite) delivery also needs a server rule before cached files are served.
WP Rocket, W3 Total Cache, WP Fastest Cache Use the bypass above wherever the PHP drop-in runs. Configure any direct cached-file delivery separately. Automatic compatibility is not claimed.
LiteSpeed Cache Exclude token requests before the server cache lookup. The plugin also marks responses non-cacheable through LiteSpeed's hook and header.
Apache, CloudFront, managed hosting Bypass both lookup and storage, and forward the token header. If you can't, turn off HTML caching on participating pages.

WP Super Cache's Simple and Expert modes run at different layers. LiteSpeed documents its no-cache response hook. Neither lets a normal WordPress plugin run before an upstream cache hit.

WordPress cache checks

Clear all page caches after changing cache settings or included content. Then run the cache checks, and add these:

  • Send a forged zeroad_variant=subscriber1 cookie, and a forged X-ZeroAd-Variant header. Neither may grant Freedom access.
  • Existing WordPress membership permissions still work as before.

These are deployment checks. The plugin's own tests don't certify third-party cache setups.

Token verification caching

Under Performance & Caching, Enable APCu Caching reuses token verification results between PHP requests when APCu is available. Without APCu, results are kept for the current request only. Cache TTL (seconds) sets how long results are kept.

This setting doesn't configure a CDN or full-page cache. Verification works without APCu.

Supported plugins reference

The tables below list the integrations in the current plugin. Depending on the integration, it uses plugin hooks, script removal or CSS. This is not a certification of every plugin version. Check your installed versions and theme with a subscriber visit.

Identifiers are the text domains the plugin checks for active plugins, unless a callback or filter is named. They are not always WordPress.org download slugs. Custom markup and plugin updates can need extra work.

Advertisements

Plugin Detection or hook
Ads For WP ads-for-wp
Ad Inserter ad-inserter
Advanced Ads advanced-ads
WP Quads quick-adsense-reloaded
AdRotate adrotate
Advanced Ads - Google AdSense In-feed advanced-ads-adsense-in-feed
AdWidget AdWidget_ callbacks
WP AdCenter wpadcenter
Corner Ad corner-ad
Ad Injection ad-injection
Simple Ads Manager simple-ads-manager
BuddyPress Ads buddypress-ads
Google Site Kit (AdSense) googlesitekit_adsense_tag_blocked filter

Raptive/AdThrive is not confirmed. Its rule checks the cmb2 text domain before removing AdThrive_Ads callbacks. But CMB2 is a separate custom-fields toolkit, so the rule doesn't reliably detect Raptive. Check your website's ads yourself.

Plugin Detection or hook
Cookiebot cookiebot
Beautiful Cookie Consent Banner bar-cookie-consent
Real Cookie Banner real-cookie-banner
GDPR Cookie Consent gdpr-cookie-consent
Pressidium Cookie Consent pressidium-cookie-consent
WPConsent wpconsent-cookies-banner-privacy-suite
GDPR Cookie Compliance gdpr-cookie-compliance
Complianz | GDPR/CCPA Cookie Consent complianz-gdpr
CookieYes | GDPR Cookie Consent cookie-law-info
Cookie Notice & Compliance for GDPR / CCPA cookie-notice
CookieAdmin cookieadmin
Cookie Notice and Consent Banner cookie-notice-and-consent-banner
Cookies and Content Security Policy cookies-and-content-security-policy
Termly - GDPR/CCPA Cookie Consent Banner uk-cookie-consent
GDPR by Trew Knowledge gdpr
Cookie Consent Box by Supsystic gdpr-cookie-consent-by-supsystic

Marketing Dialogs & Popups

Plugin Detection or hook
Popup Maker popup-maker
OptinMonster optin-monster-api
Popup Maker WP SGPM callbacks
Popup by Supsystic popup-by-supsystic
PopupKit popup-builder-block
Popup Anything - A Marketing Popup popup-anything-on-click
Advanced Popups advanced-popups
Popup Box ays-popup-box
Depicter - Popup & Slider Builder depicter
FooBox Image Lightbox foobox-image-lightbox
MailOptin Lite mailoptin
Poptin poptin
Popup Builder popup-builder
Popups for Divi divi-popup
Hustle hustle
WP Popups Lite wp-popups-lite
Icegram Express email-subscribers
Convert Pro convertpro
Newsletter Popup newsletter-popup
Ninja Popups ninja-popups
Thrive Leads Thrive_Leads class and tve_leads_should_display filter

Convert Pro and Convert Plus. The Convert Pro rule checks convertpro and removes Convert_Plug callbacks. An extra cp_show_popup override is registered only when cp_v2_popup_enabled exists. Convert Pro and Convert Plus are separate products, so this shared override doesn't establish full support for both.

Included subscription content

Posts and pages you include are opened through:

Plugin Content access hook
Paid Memberships Pro pmpro_has_membership_access_filter
WP-Members wpmem_block

Each adapter uses the post the membership plugin supplies, so including one post doesn't unlock another. See the Paid Memberships Pro hook reference and WP-Members hook reference.

Other paywalls and custom paid features need their own integration. Freedom access only applies to included content through supported integrations. It doesn't create a website subscription or purchase, or bypass post passwords. Selecting content alone can't unlock an unsupported plugin.

Custom included access

For custom templates, use \ZeroAd\WP\Actions\SubscriptionAccess::allowsPost($post) to decide whether to show included paid content. It checks both the verified subscriber and your selection. Keep any access the visitor already has through your own membership system:

$canRead = $existingAccess || \ZeroAd\WP\Actions\SubscriptionAccess::allowsPost($post);

To include a group of content instead of selecting each post, use the zeroad_freedom_includes_post filter. This example includes a category you create:

add_filter('zeroad_freedom_includes_post', function ($included, $post) {
    return $included || has_category('freedom-included', $post);
}, 10, 2);

The filter defines which content is included. It isn't proof of membership, so use allowsPost() for the actual access decision.

  • Private, draft, password-protected and non-post/page content stays excluded.
  • Map custom paid features separately in your application. Don't grant account-management or purchase permissions.
  • Clear page caches whenever your included selection or custom mapping changes.

An already-clean, unrestricted website only needs its Publisher ID. A paywalled website isn't finished until real included access works for subscribers.