Title: StaticQ Headless
Author: goonydev
Published: <strong>September 18, 2026</strong>
Last modified: September 18, 2026

---

Search plugins

![](https://ps.w.org/staticq-headless/assets/banner-772x250.png?rev=3701340)

![](https://ps.w.org/staticq-headless/assets/icon-256x256.png?rev=3701340)

# StaticQ Headless

 By [goonydev](https://profiles.wordpress.org/goonydev/)

[Download](https://downloads.wordpress.org/plugin/staticq-headless.1.0.0.zip)

 * [Details](https://wordpress.org/plugins/staticq-headless/#description)
 * [Reviews](https://wordpress.org/plugins/staticq-headless/#reviews)
 *  [Installation](https://wordpress.org/plugins/staticq-headless/#installation)
 * [Development](https://wordpress.org/plugins/staticq-headless/#developers)

 [Support](https://wordpress.org/support/plugin/staticq-headless/)

## Description

StaticQ Headless turns WordPress into the CMS behind a Cloudflare-hosted [Astro](https://astro.build/)
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

[⌊Setup tab: connect Cloudflare, deploy the receiver Worker, and configure the Astro
frontend.⌉⌊Setup tab: connect Cloudflare, deploy the receiver Worker, and configure
the Astro frontend.⌉[

Setup tab: connect Cloudflare, deploy the receiver Worker, and configure the Astro
frontend.

[⌊Cache tab: toggle URL families, per-URL invalidation, warmup, and health checks.⌉⌊
Cache tab: toggle URL families, per-URL invalidation, warmup, and health checks.⌉[

Cache tab: toggle URL families, per-URL invalidation, warmup, and health checks.

[⌊Astro Setup wizard: connect or create a GitHub repository and deploy the frontend.⌉⌊
Astro Setup wizard: connect or create a GitHub repository and deploy the frontend
.⌉[

Astro Setup wizard: connect or create a GitHub repository and deploy the frontend.

[⌊Refresh Simulator: dry-run exactly which URLs an edit will refresh, with your 
hooks applied.⌉⌊Refresh Simulator: dry-run exactly which URLs an edit will refresh,
with your hooks applied.⌉[

Refresh Simulator: dry-run exactly which URLs an edit will refresh, with your hooks
applied.

[⌊Built-in Tutorials, rendered inside wp-admin.⌉⌊Built-in Tutorials, rendered inside
wp-admin.⌉[

Built-in Tutorials, rendered inside wp-admin.

## 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

 *   [ goonydev ](https://profiles.wordpress.org/goonydev/)
 *   [ philooo ](https://profiles.wordpress.org/philooo/)

[Translate “StaticQ Headless” into your language.](https://translate.wordpress.org/projects/wp-plugins/staticq-headless)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/staticq-headless/),
check out the [SVN repository](https://plugins.svn.wordpress.org/staticq-headless/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/staticq-headless/)
by [RSS](https://plugins.trac.wordpress.org/log/staticq-headless/?limit=100&mode=stop_on_copy&format=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.

## Meta

 *  Version **1.0.0**
 *  Last updated **6 days ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.4 or higher **
 *  Tested up to **7.1.2**
 *  PHP version ** 8.1 or higher **
 * Tags
 * [astro](https://wordpress.org/plugins/tags/astro/)[cache](https://wordpress.org/plugins/tags/cache/)
   [cloudflare](https://wordpress.org/plugins/tags/cloudflare/)[headless](https://wordpress.org/plugins/tags/headless/)
   [performance](https://wordpress.org/plugins/tags/performance/)
 *  [Advanced View](https://wordpress.org/plugins/staticq-headless/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/staticq-headless/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/staticq-headless/reviews/)

## Contributors

 *   [ goonydev ](https://profiles.wordpress.org/goonydev/)
 *   [ philooo ](https://profiles.wordpress.org/philooo/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/staticq-headless/)