# Caching Compatibility

Page caching can interfere with the age gate if not configured correctly. This guide explains which caching solutions work, which don't, and how to configure them.

## How the Age Gate Interacts with Caching

The age gate relies on the MU plugin (`xyz-age-gate-redirect.php`) running PHP code on every page load to check:

1. Whether the visitor is from an age-gated region (Cloudflare headers)
2. Whether the visitor has a valid verification cookie
3. Whether the visitor is logged in

Page caching works by serving a static HTML file *instead* of running PHP. If a cached page is served, the MU plugin never runs, and the age gate is bypassed.

## Compatible Cache Plugins

The following cache plugins work correctly with the age gate because they respect the standard WordPress loading order, where MU plugins execute before the cache serves content:

### W3 Total Cache

**Compatible** with proper configuration.

**Required setup:**

1. Go to **Performance > Page Cache > Advanced**.
2. Add `age-gate` to the "Never cache the following pages" list.
3. Under "Rejected cookies," add `xyzav_verified` — this ensures that page cache varies by the verification cookie.

### WP Super Cache

**Compatible** with proper configuration.

**Required setup:**

1. Go to **Settings > WP Super Cache > Advanced**.
2. Add `/age-gate/` to the "Rejected URL Strings" list.

### LiteSpeed Cache

**Compatible** with proper configuration.

**Required setup:**

1. Go to **LiteSpeed Cache > Cache > Excludes**.
2. Add `/age-gate/` to the "Do Not Cache URIs" list.

### Other Cache Plugins

Most cache plugins that use the standard WordPress object cache or page cache mechanism will work as long as you exclude the `/age-gate/` page from caching. Check your cache plugin's documentation for how to exclude specific URLs.

## Incompatible: WP Rocket

**WP Rocket is NOT compatible with this plugin.**

### Why It Doesn't Work

WP Rocket uses a `advanced-cache.php` drop-in that serves cached pages *before* WordPress loads — including before MU plugins. This means:

1. A visitor from an age-gated region visits your site.
2. WP Rocket intercepts the request and serves a cached HTML page.
3. The MU plugin never runs.
4. The visitor sees your content without age verification.

### Why "Never Cache Cookies" Doesn't Help

WP Rocket's "Never cache pages for these cookies" setting does the *opposite* of what's needed. It prevents caching for visitors who *have* the cookie — meaning verified visitors get uncached (slower) pages, while unverified visitors (who lack the cookie) continue to get the cached page that bypasses the age gate.

### No Workaround Available

There is currently no way to make WP Rocket compatible with this plugin. WP Rocket would need to add a feature to conditionally serve cached pages based on cookie *absence* (serve cached only when the verification cookie is present), which is the reverse of their current cookie-based exclusion logic.

If you are currently using WP Rocket and need age verification, you will need to switch to a compatible caching solution.

## General Cache Configuration Rules

Regardless of which cache plugin you use:

1. **Always exclude `/age-gate/` from caching.** The age gate page must be dynamically generated on every request so the verification interface works correctly.

2. **Consider cookie-based cache variation.** If your cache plugin supports it, vary the cache by the `xyzav_verified` cookie. This ensures that verified and unverified visitors see different cached versions (or that unverified visitors are never served cached pages).

3. **Test after configuring.** Use [Test Mode](07-test-mode.md) with an incognito window to verify that the age gate activates correctly with your cache plugin enabled.

## Object Cache / Database Cache

Object caches (Redis, Memcached) and database query caches do NOT interfere with the age gate. These cache database queries and computed values, not full page HTML. They are fully compatible.

## CDN Caching

If you use Cloudflare's CDN cache (or another CDN), ensure that HTML pages are not being cached at the CDN level for age-gated content. By default, Cloudflare does not cache HTML pages (its `cf-cache-status` header shows `DYNAMIC` for HTML), so this is usually not an issue. If you've added page rules to cache everything, add an exception for your age-gated paths.

## Next Steps

- [Troubleshooting Common Issues](09-troubleshooting.md)
- [Installation Guide](01-installation-guide.md)
