A deploy button is one HTTP request
Static sites need rebuilding when content changes. It is tempting to believe your CMS provides that capability. It almost certainly does not — it provides a button, and the button posts to a URL.

TL;DR
The deploy capability lives in your host’s hook URL, not in your CMS. Anything that can send a POST can replace the admin panel button: a cron job, a webhook, a bookmark.
A static site has to be rebuilt when its content changes. If the content lives in a CMS, the natural place for that trigger is the CMS admin panel, and so that is where it usually ends up.
Then you consider moving the content somewhere else, and the button feels like a reason not to.
What the button actually is
Here is the whole thing, more or less:
export async function POST() {
const { user } = await payload.auth({ headers: await getHeaders() })
if (!user) {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
const response = await fetch(process.env.FRONTEND_DEPLOY_HOOK!, { method: 'POST' })
return response.ok
? Response.json({ success: true })
: Response.json({ error: 'Deploy hook failed' }, { status: response.status })
}An auth check, and a POST to a URL your host gave you. That is the entire deploy system. The CMS contributes two things: somewhere to click, and a guard on who may click it.
Four replacements
- A scheduled build with a change check. Cron asks the content source for the newest edit timestamp and skips the build if nothing moved. Nothing to remember, nothing to press.
- A webhook from wherever the content lives. Most content tools can fire an HTTP request when a status property changes. That is the same button, closer to the writing.
- A bookmark. Deploy hook URLs are unguessable and the blast radius of a leak is a wasted build. A bookmarklet is a legitimate answer.
- A
workflow_dispatchjob. A run button in the repository, with real authentication behind it, if you would rather the trigger live next to the code.
If a capability is one HTTP request, it is not a reason to keep a system. It is a reason to notice you were keeping the system for something else.
The part that is genuinely harder
Losing the button costs nothing. Losing save-time validation is the real question, and it deserves a straight answer rather than a reassuring one.
A CMS rejects one bad document at the moment it is saved, next to the field that is wrong, in language the person typing can act on. A build rejects the whole queue, in a log, minutes later, and blocks everyone else’s finished work until someone reads it.
| Rejected at save | Rejected at build | |
|---|---|---|
| Who sees it | the author | whoever reads logs |
| What it blocks | one document | every queued document |
| Feedback delay | immediate | one build |
For a single author who triggers their own builds, all three rows collapse to nothing: you broke it, you read the log, thirty seconds apart. For five authors, two of whom do not have repository access, that table is the entire argument for keeping a CMS.
The actual decision
Not can we replace the button — you can, four ways, this afternoon. It is whether the number of people writing, times their distance from the build, is large enough that catching mistakes at save time is worth an admin panel, a database and a deployment to maintain.
Answer that honestly and the button never enters into it.

