Accept-aware disk page cache for WordPress, served directly by nginx. Caches text/html and text/markdown variants independently — nginx picks the right file per-request before PHP is ever invoked.
The plugin buffers WordPress responses and writes them to disk. On the next request, nginx serves the cached file at static-file speed — no PHP, no database.
Two variants are cached independently per URL:
| Accept header contains | Cached as | nginx serves |
|---|---|---|
text/markdown |
index.md + .md.gz |
markdown to LLM/API clients |
| anything else | index.html + .html.gz |
HTML to browsers |
A headers sidecar (index.html.headers / index.md.headers) stores the original response headers in plaintext HTTP format for future Lua/njs injection without PHP.
- Atomic disk writes — no partial reads by nginx
- Pre-compressed
.gzsiblings (gzip_static on) and.brsiblings when ext-brotli is loaded - Smart invalidation: per-URL purge on
save_post, full flush on structural changes (theme switch, permalink change, plugin/core upgrades) - Varnish purge integration: per-URL
PURGEand full-flushBAN /scoped byX-Cache-Tag-Prefixfor multi-tenant fleets - HTML minification on cache write (15–25% size reduction before gzip)
- Analytics tracking parameters (
utm_*,fbclid,_ga*, etc.) treated as cache-transparent — decorated URLs share one cache file with their bare-path counterpart X-Cached-By: sqrd-page-cachediagnostic header on nginx cache HITs- Admin settings page with live nginx config preview and one-click purge
- Admin bar "Purge Cache" shortcut for logged-in admins
- All nginx config scoped to the vhost — zero
http { }pollution
- PHP 8.3+
- nginx with
gzip_staticsupport - WordPress 6.4+
- A theme or plugin that renders
text/markdownresponses — this plugin only caches, it does not generate markdown
1. Install the plugin
# Upload sqrd-page-cache/ to /wp-content/plugins/, then:
composer install --no-dev --optimize-autoloaderActivate through Plugins in WordPress admin, then visit Settings → SQRD Page Cache.
2. Configure nginx
Add one include to your server { } block, above location / { }:
# Inside server { }, ABOVE location / { }
include /path/to/wp-content/plugins/sqrd-page-cache/nginx/sqrd-page-cache.conf;Update your location / { } to try the cache file first:
location / {
try_files $sqrd_cache_file $uri $uri/ /index.php?$args;
}Reload nginx:
nginx -t && systemctl reload nginxThe full annotated example is in nginx/example-server.conf and shown live in the Settings page.
SQRD Page Cache applies the same rule in both PHP and nginx:
If
Acceptcontainstext/markdown(case-insensitive) → md variant. Otherwise → html.
Your markdown-rendering code must use the same rule. If you ever need RFC 7231 q-value parsing, update sqrd\Cache\Negotiation::ext_for_accept() and the if ($http_accept ~* "text/markdown") block in the nginx include in lockstep.
Add paths or regexes to Exclude paths in the settings page (one per line). For WooCommerce:
/cart
/checkout
/my-account
For cookie-based bypasses (e.g. WooCommerce cart), extend the nginx cookie regex in sqrd-page-cache.conf:
if ($http_cookie ~* "(wordpress_logged_in_|woocommerce_items_in_cart)") {Both the PHP exclude list and the nginx cookie pattern must stay in sync.
| Filter | Default | Description |
|---|---|---|
sqrd_page_cache/respect_donotcachepage |
false |
Set to true to honour the DONOTCACHEPAGE constant |
sqrd_page_cache/tracking_params |
built-in list | Add extra tracking parameter patterns (supports * suffix glob) |
sqrd_page_cache/minify_html_options |
configured HtmlMin instance |
Swap or reconfigure the HTML minifier — accepts any object with minify(string): string |
sqrd_page_cache/significant_headers |
standard list | Extend which response headers are written to the .headers sidecar |
Enabled by default. Toggle under Settings → SQRD Page Cache. Strips redundant whitespace and HTML comments before the file is persisted. Inline <script>, <style>, <pre>, <textarea>, and IE conditional comments are protected automatically. Markdown variants are never minified.
Per-region opt-out:
<nocompress>…this block is not minified…</nocompress>Closing tags (</html>, </body>, </p>, etc.) and attribute quotes are always preserved.
composer install
composer test # Pest test suite
composer test:coverage # with coverageTests cover: Headers, Minifier, Negotiation, Output, Paths, Store, Varnish.
GPL-2.0-or-later