StaticQ Headless

Description

StaticQ Headless turns WordPress into the CMS behind a Cloudflare-hosted Astro frontend. Editors keep the familiar WordPress admin; visitors get static-fast pages served from Cloudflare’s edge and a durable R2 cache; and the plugin keeps both sides in sync automatically, without a full rebuild, a cron job, or a manual cache purge on every edit.

When you publish, update, unpublish, or reschedule a post, the plugin works out exactly which URLs changed (the post’s permalink, the archives and paginated archives it appears on, the relevant feeds, and the sitemap) and refreshes only those. Nothing else is touched, so a single edit never invalidates your whole site.

Important: everything the plugin does runs against your own Cloudflare and GitHub accounts, using credentials you provide. StaticQ Headless does not send your content or credentials to any StaticQ-operated server. There is no telemetry and no phone-home. See External services below.

What it does

  • Per-URL cache invalidation. On each editorial change the plugin computes the impacted URL set with a dedicated URL-impact engine (post, home archive, term archives with correct pagination, author archive, feeds, sitemap) and dispatches just those URLs to a small Cloudflare Worker you deploy from the setup wizard (the “receiver”). The receiver is what purges Cloudflare’s edge cache for those URLs, or drops the stored copy in R2 so the frontend re-renders it on the next request. WordPress only ever sends the list of changed URLs, so your WordPress install never needs Cloudflare cache-purge permissions.
  • Two-layer edge delivery. The Astro frontend serves pages from Cloudflare’s edge cache backed by a durable R2 store, so pages stay fast even after the edge cache evicts them, and cold renders are smoothed out.
  • Managed Astro frontend deploy. From wp-admin you connect a GitHub repository (or create a new private one, generated from the public StaticQ Astro starter template so GitHub populates it server-side, with no local git binary and nothing written to your WordPress server), provisions the Cloudflare Worker and R2 bucket, syncs the GitHub Actions variables and secrets, and triggers the deploy. From then on, editing the frontend is a normal git push.
  • REST “speed layer” for Astro. Batched-query REST endpoints under /wp-json/sqheadless/v1/ (site config, homepage, archive, single, SEO head, sitemap) collapse WordPress’s _embed N+1 fan-out into a handful of SQL queries, for much faster SSR on media-heavy archives. The frontend uses them automatically and falls back to standard WordPress REST when they are absent.
  • Cache warmup. Prime the edge cache by enumerating every archive and post URL and dispatching them ahead of your visitors.
  • Rendered-content cache (optional). Persists rendered post HTML on the WordPress side and re-renders only when the post changes, smoothing cold-render spikes on shortcode- and gallery-heavy content.
  • SEO-plugin aware. If Rank Math or Yoast is active, the frontend uses that plugin’s own <head> and structured data; breadcrumb schema is filled in when your SEO plugin does not emit it. No SEO plugin required.
  • Built-in tutorials. Step-by-step guides ship inside the plugin under StaticQ Headless → Tutorials, always matching your installed version, including how to bring your own Astro templates into the deploy pipeline.
  • Extensible. A documented action and a set of filters let you add URLs to the refresh set, register custom pages, or observe every editorial event. A Refresh Simulator dry-runs the engine with your hooks so you can see exactly what an edit would invalidate.

Bring your own Astro templates

The StaticQ Astro starter (the repository the wizard generates into your GitHub account) is a starting point, not a straitjacket. Replace its pages and components with your own design and deploy through the same managed pipeline (connect your repository and push). The one requirement is that your project keeps the plugin’s caching contract that the starter ships with (the edge/R2 middleware, the cache-key module, and the WordPress data client), so per-URL invalidation keeps working. The built-in Tutorials cover exactly what to keep.

External services

StaticQ Headless connects to external services only when you ask it to (during setup and deploy actions in wp-admin, and when your content changes), and only to accounts and endpoints you configure. It never contacts a StaticQ-operated service, and it sends no analytics.

A note on bundled code: the receiver Worker the plugin uploads to your Cloudflare account ships inside the plugin as a small prebuilt bundle (assets/worker/dist.js, ~13 KB). Its full human-readable TypeScript source ships right next to it in assets/worker/src/, with build instructions and an integrity hash in assets/worker/README.md.

1. Cloudflare API (https://api.cloudflare.com).
Used when you configure and deploy the Cloudflare side from the Setup tab and the Astro Setup wizard (all admin-triggered, never on the front end and never automatically). Using the Cloudflare API token, account ID, and zone ID you enter, the plugin creates and updates the receiver Worker (uploading its bundled script), provisions the frontend Worker and an R2 bucket, sets Worker variables and secrets, manages the workers.dev subdomain, and binds a custom domain. This is your own Cloudflare account. Cloudflare terms: https://www.cloudflare.com/website-terms/ (privacy policy: https://www.cloudflare.com/privacypolicy/).

2. GitHub API (https://api.github.com).
Used when you set up and deploy the Astro frontend (the Astro Setup wizard), and only when you trigger those actions. Using a GitHub personal access token you provide, the plugin verifies or creates a repository (a new one is created by generating it from the public StaticQ Astro starter template at https://github.com/daixtech/staticq-headless-starter, which GitHub copies into your account server-side), sets GitHub Actions variables and (libsodium-encrypted) secrets, and dispatches and monitors the deploy workflow. This is your own GitHub account. GitHub terms: https://docs.github.com/site-policy/github-terms/github-terms-of-service (privacy statement: https://docs.github.com/site-policy/privacy-policies/github-privacy-statement).

3. Your receiver endpoint (a URL you configure).
When content changes (and when you use the manual refresh or warmup tools), the plugin POSTs to the URL you set, normally the Cloudflare Worker you deployed above. The request contains the list of changed absolute URLs plus basic post metadata (event type, post ID, post type) and your site’s home_url(), signed with an HMAC secret for authenticity. No API tokens or account IDs are ever sent to this endpoint. Because the URL is yours, its terms are yours.

Screenshots

Installation

  1. Upload the staticq-headless folder to /wp-content/plugins/, or install the plugin ZIP from Plugins → Add New → Upload Plugin.
  2. Activate the plugin through the Plugins screen.
  3. Open StaticQ Headless → Settings. The Setup tab walks you through connecting Cloudflare and deploying the receiver Worker.
  4. Open StaticQ Headless → Astro Setup and follow the wizard to connect or create a GitHub repository and deploy the Astro frontend.
  5. New to it? StaticQ Headless → Tutorials has step-by-step guides.

Recommended: keep secrets in wp-config.php

For production, define credentials as constants in wp-config.php (above the “That’s all, stop editing!” line) instead of storing them in the database. When a constant is defined it takes precedence and the matching field renders read-only.

define( 'SQHEADLESS_CF_API_TOKEN', '...' );
define( 'SQHEADLESS_CF_ACCOUNT_ID', '...' );
define( 'SQHEADLESS_CF_ZONE_ID', '...' );
define( 'SQHEADLESS_PER_URL_SECRET', '...' );

For the managed Astro deploy, a GitHub token constant is used:

define( 'SQHEADLESS_AA_GITHUB_TOKEN', 'ghp_...' );

Additional optional constants (receiver-only tokens, site-gate cookies, per-install worker/bucket suffix) are documented in the plugin’s docs.

Requirements

  • WordPress 6.4 or newer, PHP 8.1 or newer.
  • A Cloudflare account (Workers + R2) for the edge delivery side.
  • A GitHub account and a classic personal access token with repo and workflow scopes, for deploying and updating the Astro frontend.
  • PHP libsodium (bundled with PHP 7.2+) is used to encrypt GitHub Actions secrets; if it is unavailable the wizard falls back to manual guidance.
  • No shell access, proc_open, or git binary is required.

FAQ

Does StaticQ Headless host my site?

No. It deploys to your Cloudflare account and your GitHub repository. You own the infrastructure and the code.

Does it send my content or credentials to StaticQ?

No. The plugin only contacts your own Cloudflare and GitHub accounts (endpoints you configure) and the receiver URL you set. There is no telemetry and no author-operated service. See External services.

Do I have to use the StaticQ Astro starter as-is?

No. It is a starting point: you can replace its pages and components with your own Astro design and deploy through the same pipeline, as long as your project keeps the plugin’s caching contract (the edge/R2 middleware, cache-key module, and WordPress data client the starter ships with). The built-in Tutorials cover this.

Do I need the GitHub and Cloudflare setup?

Yes, for the headless setup this plugin is built for. The fast edge + R2 delivery comes from the Cloudflare Worker and the Astro frontend, and the frontend is deployed and kept in sync through GitHub. (Internally the invalidation engine simply POSTs the changed URLs to a receiver URL, but the supported, complete experience is the Cloudflare + Astro pipeline.)

Is a full rebuild triggered on every edit?

No. That is the point: the plugin computes the specific URLs a change affects and refreshes only those, so publishing costs the same whether the site has fifty pages or fifty thousand.

Does it require shell access or proc_open?

No. Repository creation and the starter push happen over the GitHub API. Nothing is executed on your server.

Which SEO plugins are supported?

Rank Math and Yoast are detected automatically and their <head> and schema are used by the frontend. Neither is required; the plugin fills in breadcrumb structured data when the SEO plugin does not.

How do I extend which URLs get refreshed?

Use the sqheadless/object_urls, sqheadless/affected_objects, and sqheadless/static_archive_urls filters (and the sqheadless/content_change action to observe events). The Refresh Simulator on the Cache tab dry-runs your hooks and shows the exact URL list. A full reference ships with the plugin.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“StaticQ Headless” is open source software. The following people have contributed to this plugin.

Contributors

Translate “StaticQ Headless” into your language.

Interested in development?

Browse the code, check out the SVN repository, or subscribe to the development log by RSS.

Changelog

1.0.0

  • Initial release.
  • In-admin tutorials: a simple, AI-agent-first track (default) and a full advanced track with the reference docs, all readable under StaticQ Headless Tutorials.
  • Brand section: set the site logo from the plugin (theme-independent; feeds the site-config endpoint and stays in sync with the theme’s own logo).
  • Live “Last deploy” status on the Astro tab: green check / red cross / in-progress, run number, date, and a link to the GitHub Actions run.
  • Warmup URL-list export (CSV/JSON) and a per-URL warmup outcome log.
  • Per-URL cache invalidation engine (post, archives with pagination, author, feeds, sitemap), dispatching either an edge purge or a render-to-R2 warm fetch.
  • HMAC-signed, timestamped dispatch to a user-configured receiver.
  • Two-layer edge delivery (Cloudflare edge cache backed by durable R2) via the StaticQ Astro starter frontend.
  • Cache warmup and priming.
  • REST speed-layer endpoints under /wp-json/sqheadless/v1/ for fast Astro SSR, with graceful fallback to standard WP REST.
  • Optional rendered-content cache.
  • Password-protected posts are never exposed through the speed-layer endpoints: content and excerpt come back empty with protected set, matching WordPress core’s own REST behaviour.
  • Managed Astro frontend deploy over the GitHub API (generate a repo from the public StaticQ starter template or connect an existing one, provision Cloudflare Worker + R2, sync CI variables and secrets, trigger deploy), with no git binary or proc_open. No frontend code ships inside the plugin.
  • Rank Math and Yoast head and structured-data passthrough, with automatic breadcrumb schema fallback.
  • Refresh Simulator and extension hooks (sqheadless/content_change, sqheadless/object_urls, sqheadless/affected_objects, sqheadless/static_archive_urls, sqheadless/impact_urls).
  • Built-in, version-matched tutorials in wp-admin.