Skip to content
← Back

Lesson 5 of 6

Choose Cloudflare Workers or Pages

Pick Workers with static assets or Pages from current official behaviour, write a decision note, and preview locally on the matching port — without deploying yet.

The honest current picture

Cloudflare has two overlapping hosts. Pages is a static-asset host with optional Pages Functions. Existing Pages projects keep working. Workers is a compute platform that can also serve static assets from the same deploy. Current docs present Workers as the way to ship full-stack apps, and a Pages→Workers migration guide exists because newer features land on Workers first.

Two facts from that guide: static-asset requests are free on both, and Pages Functions invocations are charged like Workers — check current pricing yourself; this course does not promise a free tier. Workers has the broader set: Durable Objects, Cron Triggers, Workers Logs, gradual deployments. Neither is wrong. Pick the one whose behaviour you can explain.

The ordering difference that bites

Behaviour Pages Workers static assets
Files upload / build output dir assets.directory in Wrangler config
Missing routes auto from index.html / 404.html explicit not_found_handling
Request order Functions run ahead of assets assets run ahead of the Worker unless run_worker_first
Local preview npx wrangler pages dev <dir> default 8788 npx wrangler dev default 8787
Deploy npx wrangler pages deploy <dir> --project-name <name> npx wrangler deploy
Custom domain whose nameservers are not on Cloudflare supported (CNAME) not supported

This tracker is one index.html, no client routing, no server code, so ordering does not matter yet. It matters the moment you add /api/*. File-based functions/ routing is first-class on Pages (functions/api/health.js → /api/health). Workers has no equivalent folder; you write a main script.

Decision table and Workers config for this app

New static app, maybe a small API later → Workers with static assets. Existing Pages project with a URL you cannot break → stay on Pages. Nameservers outside Cloudflare → Pages. Cron, Durable Objects, Workers Logs → Workers. Drag a folder in the dashboard → Pages upload is shortest.

For a brand-new tracker, choose Workers. Create wrangler.jsonc next to public/ (not inside it). Set compatibility_date to the date you create the file (example 2026-09-13). $schema is optional editor help and only resolves if Wrangler is installed locally (npm install -D wrangler); npx wrangler works without that.

{
  "name": "task-tracker-yourname",
  "compatibility_date": "2026-09-13",
  "assets": {
    "directory": "./public"
  }
}

name is lowercase and unique. assets.directory must be the folder that contains index.html. Omit main — no Worker script yet. You do not need not_found_handling for this one-page app. Do not put secrets in vars; those are plaintext.

Write the decision and preview locally

Create a Cloudflare account at dash.cloudflare.com and verify email if you have not. Then:

npx wrangler login
npx wrangler whoami

If the browser cannot reach localhost for the OAuth callback, use npx wrangler login --device.

Workers preview (port 8787):

cd ~/projects/task-tracker
npx wrangler dev

Pages preview (port 8788) if you chose Pages — no config file required for a static-only project:

npx wrangler pages dev ./public

Confirm the tracker loads and that you did not upload the repo root (that would publish notes and config). Write DECISION.md: target; two reasons tied to ordering, routing, domains, or the matrix; one capability you are giving up.

Sources

How did this lesson go? Give feedback →