Deploy to Cloudflare
On every publish, Menestrel calls your Cloudflare project’s deploy hook: the build restarts from the Git repository and the site picks up the published snapshot. Cloudflare comes in two flavors, and Menestrel supports both:
- Workers Builds: the current platform, where Cloudflare steers new projects. Deploy hooks have been official there since April 2026. It is the default choice for a new site.
- Cloudflare Pages: the historical offering, still supported. If your site already runs on Pages, there is nothing to migrate. It is also the only flavor with real status tracking (see step 3).
Prerequisites: a Worker or a Pages project connected to a Git repository (deploy hooks only exist for those), and a site wired to the Menestrel loader (see Your first site).
-
Create the deploy hook on Cloudflare
On Workers Builds: in Workers & Pages, select your Worker, then Settings > Builds > Deploy Hooks. Give it a name (for example
menestrel), pick the production branch, then copy the generated URL:https://api.cloudflare.com/client/v4/workers/builds/deploy_hooks/xxxxxxxxOn Cloudflare Pages: select the Pages project, then Settings > Builds > Add deploy hook. The URL looks like:
https://api.cloudflare.com/client/v4/pages/webhooks/deploy_hooks/xxxxxxxxMenestrel only accepts
httpsURLs on theapi.cloudflare.comhost. Any other URL is rejected when the target is created. -
Connect the target in Menestrel
In the admin, open “Site settings”, the “Deployment” tab, then “Connect a host”. Pick the Cloudflare provider, then under “Type” choose
workers_buildsorpages, matching where you created the hook. Give the target a name (for example “Cloudflare prod”) and paste the URL into “Deploy hook URL”. The three other fields are optional: you can already save with “Connect”. -
Enable build tracking (Pages only)
For a
pagestarget, Menestrel can follow each build all the way to “Live” or “Failed”, with a link to the Cloudflare deployment. Fill in the three optional fields; all three are needed, two out of three is not enough:- “API token”: a token created on
dash.cloudflare.com/profile/api-tokens, with read permission on Cloudflare Pages. Menestrel only uses it to read the project’s deployment list, never to act on it. - “Account id”: the Cloudflare account identifier, visible in the dashboard URL (
dash.cloudflare.com/<account id>). - “Project name”: the Pages project name, the one from the
<name>.pages.devURL.
For a
workers_buildstarget, Menestrel does not track builds yet: the deployment stops at “Triggered” as soon as the hook answers. To check the build itself, open the Worker’s build history: the “Triggered by” column shows the hook’s name. - “API token”: a token created on
-
Test the target
The “Test” button really calls the hook: Cloudflare runs an actual build, without publishing anything new. It is not a simulation; a test that builds nothing would prove nothing. If the hook answers, the admin shows “Host reached, deployment triggered.”; otherwise “Test failed” with the error code. The build itself is checked on the Cloudflare side: the Worker’s build history, or the Pages project’s deployment list.
-
Set the build environment variables
On Workers Builds: in the Worker, Settings > Build, “Build variables and secrets” section (runtime variables, set elsewhere, are not visible to the build). On Pages: the project’s Settings > Environment variables. In both cases, set:
Fenêtre de terminal MENESTREL_CONTENT_URL=https://content.menestrel.dev/p/prj_xxx/pk_xxxThe loader then reads the published snapshot straight from the CDN: the build passes even if the Menestrel application is down or in maintenance. Do not set
MENESTREL_TOKENin production. Variables are detailed in Environment variables.
What Menestrel sends to Cloudflare
Section titled “What Menestrel sends to Cloudflare”On every trigger, Menestrel sends a bare POST to the hook, with no body and no parameter: Cloudflare deploy hooks do not accept a label. Unlike Netlify, the build therefore does not display the snapshot id; the link between a publish and a build lives under “Recent deployments”, on the Menestrel side.
With tracking enabled (pages target), Menestrel polls GET https://api.cloudflare.com/client/v4/accounts/<account id>/pages/projects/<project name>/deployments with the token: first 15 seconds after the trigger, then at widening intervals up to one minute, for at most 45 minutes. The status of the build’s last stage (latest_stage) is authoritative: active shows as “Building”, success becomes “Live”, failure becomes “Failed”, canceled becomes “Cancelled”.
Reading the states under “Recent deployments”
Section titled “Reading the states under “Recent deployments””| State | Meaning |
|---|---|
| Queued | Menestrel queued the trigger. |
| Triggered | The hook answered. Final state for workers_builds, or for pages without tracking. |
| Building | Cloudflare is building the site (pages with tracking). |
| Live | The deployment is being served. |
| Failed | The build failed, or the hook stayed unreachable. |
| Cancelled | Deployment cancelled on Cloudflare, target unavailable at trigger time, or a queued build superseded by a newer publish. |
Repeated failures: pausing
Section titled “Repeated failures: pausing”A failed trigger is retried, at most three attempts per build. After three consecutive failures, the target goes “Paused” and Menestrel stops calling it: hammering a broken hook fixes nothing and drowns the history. Fix the cause (hook deleted on Cloudflare, wrong URL, expired token), then click “Resume”. The failure counter resets and publishing rebuilds the site again.