Cloudflare Pages Cron Deploys

11ty cloudflare devops eleventy
Reading time:
About 3 min

Cloudflare Pages are great to host static sites like 11ty. Cloudflare also supplies workers that can be configured on cron jobs for various things, like deploying your static site. And to get build-time webmentions to update, deploying daily feels like the right thing to do.

  • This post assumes you already have Cloudflare Pages setup to host your static site
  • Thanks to this Codemzy post for laying out the rough plan

Why (AKA Webmentions)

Worked a bit to get webmentions all wired up on the site! Thanks a ton to Bob Monsour and Robb Knight and a bunch of others for their posts, inspiration, and initial 11ty code and designs to use as examples.

The beauty of the webmentions is that they pull mastodon comments only at build(!) time. This is pretty great as it requires no client-side JS to make the magic happen. The downside is that webmentions won’t show up until a build happens.

Now ideally we could trigger builds whenever a mention happens. But that seems like overkill. So as a compromise I wanted to setup builds twice a day. Which is honestly already optimistically too many builds – plus Cloudflare gives 500 builds a month, so using 60 builds still seems like a lot. So I decided to dial it back to 1 build a day.


  1. Setup A Deploy Webhook
  • From Workers & Pages > Overview click into your project
  • Then under Settings > Builds & Deployments click to Add deploy hook
  • Give it a name like scheduled-deploys
  • Copy the deploy hook with the api key on it
  1. Setup the Worker
  • From Workers & Pages > Overview click Create application
  • Then Create Worker
  • Give it a name like scheduled-deploys and click Deploy
  1. Edit the Code

Here’s what I ended up with. Nothing too fancy.

Updated 2024-01-16 to run only on cron schedules. The old version ran too often via HTTP request somehow

async function triggerDeploy(request, env, ctx) {
  const deployHook = "<paste your deploy hook here>";

  await fetch(deployHook, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",

  return "Deploy initiated";

export default {
  // See
  async scheduled(event, env, ctx) {
  // Kept disabled just to show it here.
  async fetch(request, env, ctx) {
    return new Response("Noop. This worker only works on a cron schedule.");
  • Once done, click Save and deploy
  1. Setup a Cron Trigger
  • On the worker page, click on the Triggers tab
  • Click to Add Cron Trigger
  • Setup how often you’d like yours to run. I went with 0 9 * * * to run at 9:00UTC daily which is 5AM US EST (or EDT I don’t know, timezones are my kryptonite)
  • Take a peek at the “execution summary” area to see that it runs at the times you expect. Kinda nice because cron triggers are always kinda confusing 🙃
Cloudflare Cron Trigger
  1. Disable the Route added 2024-01-16
  • For some reason, Cloudflare seems to execute the route (or something hits the route) a bunch of times a day. So I’d advise disabling it
  • This way only the cron trigger will enable this worker
  1. Check it in the morning

And with any luck, maybe there will even be a webmention at the bottom of this post in the morning. Or maybe not. But either way the cron job will deploy it 😍

💬 Discuss on Mastodon

1 Comment 💬