Skip to main content
The AnonAge plugin puts an age gate in front of your WordPress content. It works immediately with no account, no API key and no cost, and upgrades to a real identity-backed check when you need one.

Free to start

Both self-declaration modes work with no AnonAge account at all.

Cache-safe

Nothing to configure in WP Rocket, LiteSpeed, W3TC or Cloudflare.

Keeps you findable

Gate the restricted part of a page and leave the rest indexable.

No third parties

No tracking, and the QR code is generated on your own server.

Install

1

Add the plugin

Upload it to /wp-content/plugins/, or install it from the Plugins screen, then activate it. Requires WordPress 6.0 and PHP 7.4 or newer.
2

Open the settings

Everything lives under Settings → AnonAge.
3

Choose a mode and an age

Pick how visitors prove their age, set the minimum age, and save. That is enough for a working gate.

The two decisions that matter

Everything else is detail. These two settings are independent, and getting one right and not the other achieves nothing.
Self-declaration is a statement by the visitor, not a check. It is what most sites run and it is a reasonable default, but it is not “highly effective age assurance” under the UK Online Safety Act or its equivalents. Verified mode is.
Choosing Verified with Cover the page means paying for a real identity check and then protecting the content with an overlay a visitor removes in one click. The plugin warns you when you save that combination. It is allowed — some sites want the check without hard gating — but it does not enforce anything.

Settings

The AnonAge Gate settings tab in WordPress

The Gate tab: mode, minimum age, what it applies to, enforcement level, and how long a visitor stays through.

Choosing what to gate

Every page. Simple, and the right answer for a site that is entirely age-restricted — but in “Withhold the whole page” mode it also means search engines see nothing but the gate on every URL.
Tick the pages to gate. The picker shows your page hierarchy, and ticking a parent covers all of its children — child pages are marked “gated via parent” so you can see what is covered without having to work it out. Add posts or other post types by ID.Inheritance follows the page hierarchy rather than the URL, so it still works on sites whose permalinks are not hierarchical.
One path per line. A path ending in a slash covers everything beneath it, so /gated/ gates that page and every child page under it. * works as a wildcard.
Everything you do not list stays open and indexable.

Minimum age

Only 13, 16, 18 and 21 are offered. These are the thresholds the AnonAge API supports, and keeping self-declaration on the same list means switching to verified mode later never quietly changes the age you enforce.

How long a visitor stays through

Session-only, 1 hour, 24 hours (default), 7 days or 30 days.
Do not set this meanly. In verified mode every re-check spends one of the visitor’s own monthly verifications, so a 30-minute window would exhaust an entry-tier account in a day. Anything longer than 24 hours is flagged in the settings, because some jurisdictions expect a check per session.

Appearance and content

The AnonAge Appearance settings tab

Backdrop colour, opacity and blur; panel, border and button colours; logo; and a full-screen background image.

The AnonAge Content settings tab

Every string the gate shows. Leave a field blank and the grey placeholder is used, which adapts to the minimum age you chose.

The background image is shown to everyone who has not passed the gate — including minors and search engines. Suggest what the site is with branding or atmosphere, but keep the image itself suitable for all audiences.
The AnonAge Advanced settings tab

Bypass rules, excluded URLs and roles, and debug logging.

Leave the administrator bypass on. A gate covering the editor while you are configuring it is the single most common cause of “the plugin broke my site”.

Splitting a page

In “Hide the restricted part” mode, you decide where each page is cut. Put your descriptive, keyword-carrying content above the marker and the restricted material below it. Use the [anonage_gate] shortcode, or WordPress’s own More block.
A WordPress page in the block editor with the anonage_gate shortcode dividing public content from restricted content

The block editor. Everything above [anonage_gate] is public and indexable; everything below it never leaves the server until the visitor has proved their age.

Without a marker the whole of the page content is withheld and only the title and excerpt remain public — which is fine, but it wastes the page’s SEO value.

What the visitor sees

The AnonAge age gate asking Are you 21 or over

Does it actually withhold the content?

Yes — and it is worth proving rather than asserting, because most age-gate plugins only cover the page. Here is a gated page with developer tools open. The entire <body> is the site chrome and the gate. The page content is not in the document at all:
Browser developer tools showing that the gated page contains no restricted content

Developer tools on a gated page. There is no page content to reveal.

And here is the same page with position: fixed unticked — the trick that defeats a cover-only gate. The overlay drops away, and what is underneath is the public teaser and a notice. The restricted content is still not there:
The overlay removed in developer tools, revealing only the public teaser and a notice

The overlay removed by hand. The restricted content was never sent, so there is nothing to uncover.

The restricted half is released only after the server verifies a signed cookie in PHP. Nothing the browser can be persuaded to do changes that.

Search engines

There is no way to withhold content from visitors and still have that content indexed. Serving search engines something visitors do not get is cloaking, and it is penalised. This plugin does not do it. What you can choose is granularity:

Split the page

Title, description and everything above the marker stay indexable and do the SEO work. Only the restricted part is withheld.

Split the site

Gate /gated/ or a set of pages, and keep landing, category and information pages open so the site stays findable.
“Withhold the whole page” does hide those URLs from search results, because the crawler receives the gate and nothing else. Use it only where there is nothing safe to show.

Caching

Nothing to configure. The page sent to every visitor is byte-identical: the gate is applied in the browser, and the restricted content is fetched separately over a request that is never cached.
Do not add the anonage_verified cookie to a “vary the cache on this cookie” list. It would fragment your cache for no benefit.

Membership sites

For a logged-in visitor the result is recorded against their account, not just their browser, so they verify once rather than once per device.
The state lives in user meta as _anonage_verified_until, _anonage_verified_age and _anonage_verified_mode. Delete those three keys to require a member to verify again.

Verified mode

Verified mode checks the visitor’s age against a real identity check. They scan a QR code with the free AnonAge app and your site receives a yes or no — never their name, their date of birth or their documents.
The AnonAge Connection settings tab

The Connection tab. Your secret key stays on the server; the callback URL is shown so you can confirm it is reachable.

1

Create a key

In the DashboardAPI Keys, create a key. The secret key and its signing secret are shown once — copy both.
2

Paste them into the Connection tab

The environment badge confirms whether it is a test or live key. The signing secret is what proves a result genuinely came from AnonAge; without it every verification is rejected.
3

Check the callback URL

Shown on the same tab. AnonAge posts each signed result there.
4

Switch the mode to Verified

On the Gate tab. Pair it with “Hide the restricted part” or “Withhold the whole page”.

How it works

The session is opened server-side. The QR code carries only { v, session_id, nonce, api_base } — an opaque reference that is useless to anyone but the wallet presenting it.
The callback carries X-AnonAge-Signature: t=…,v1=…, an HMAC-SHA256 over <timestamp>.<raw body>. The plugin verifies it against the raw request body and rejects anything outside a five-minute window. See Webhooks for the scheme.
Plenty of sites sit behind a firewall, on a staging domain or on localhost and will never receive an inbound callback. If none arrives within about eight seconds the plugin asks AnonAge for the result instead, up to three times. The callback is the fast path; polling is the reliable one.
That is the handshake window, fixed server-side — not the same thing as how long a visitor stays through the gate. The gate shows a countdown and offers a fresh code rather than leaving a dead QR on screen.
Opening one per pageview would spend a verification for every visitor and every crawler. There is also a per-visitor rate limit, adjustable with the anonage_session_rate_limit filter.

Requirements

Your site must be served over HTTPS. AnonAge refuses a plaintext callback URL in production. On a local or staging install, put it behind a tunnel such as ngrok or Cloudflare Tunnel — the settings screen tells you when this is the problem rather than reporting a generic failure.

Reference

Shortcode

Filters and actions

What is stored

No personal data, no analytics, no tracking. The self-declaration modes make no external requests at all.
The cookie is deliberately readable by JavaScript. The gate has to decide whether to cover the page before it paints, and it cannot ask the server without defeating full-page caching. The signature is what prevents forgery — and the claim itself is one the visitor made about themselves.

Troubleshooting

Administrators are exempt by default. Open the site in a private window, or turn off the administrator bypass on the Advanced tab.
Your site is not on HTTPS. Verified mode needs an https:// callback URL.
The key was truncated when copied, or it has been revoked. Create a new one — note that this also gives you a new signing secret, which must be updated too.
Check the signing secret is present on the Connection tab. Without it every result is rejected as unsigned. Turn on debug logging on the Advanced tab to see rejections in the PHP error log.
A page cache is serving mixed copies. This should not happen with the plugin’s own modes, but it will if something else on the site varies the HTML by visitor. Do not add the anonage_verified cookie to a cache-vary list.

Questions

Email support@anonage.io.