Cloudflare Pages to Workers
Cloudflare documents a migration from Pages to Workers with static assets
(https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/).
This skill is a checklist for that migration; it does not deploy. Before
changing anything, read Cloudflare's current guide. If the cloudflare-docs
plugin is enabled, its docs MCP also publishes a migration-guide tool next to
the search tool.
1. Inspect
wrangler.toml|json|jsonc with pages_build_output_dir, or a Pages project
configured only in the dashboard (then there is no config file to convert;
bindings and variables live in the dashboard and must be re-declared).
- A
functions/ directory (Pages Functions), a built _worker.js, _routes.json,
_headers, _redirects.
package.json scripts that call wrangler pages dev or wrangler pages deploy.
- Inspect the installed cf version, framework adapter and Node22.18+ runtime.
Preview a legacy conversion with
cf migrate --dry-run; review its local
edits and unresolved items. Do not create a new project over the old one.
2. Classify
- Assets only (no
functions/, no _worker.js): the new config needs only
name, compatibility_date and assets.directory.
- Assets plus code (a built
_worker.js, or functions/): add main
pointing to the Worker entry, and assets.binding (for example ASSETS) if the
code serves assets itself.
3. Convert the config
Use cloudflare.config.ts and the current cf/config helpers. The Worker
needs name and compatibilityDate; code also needs entrypoint. Preserve
account, bindings/IDs, compatibility behavior and domains from the Pages
project. Static assets follow the adapter's current documented output format.
If code needs an ASSETS binding, declare bindings.assets() in worker.env.
Review generated output with cf build and cf deploy --dry-run.
A built _worker.js must not become a public asset. Move it outside the assets
directory or exclude it and _routes.json in .assetsignore:
_worker.js
_routes.json
Pages excluded node_modules, .DS_Store and .git automatically; Workers
does not, so list them (**/node_modules, **/.DS_Store, **/.git) if they
are inside the assets directory.
_headers and _redirects placed in the assets directory are parsed by
Workers and keep working for static asset responses, so do not ignore them.
They are not applied to responses generated by Worker code; if the project has
Pages Functions, _worker.js, or run_worker_first, headers and redirects for
those responses must be set in code.
- If
functions/ exists, the build must compile it. keep the framework's documented Functions build adapter and set the Worker
entrypoint to its output. A legacy compatibility delegate may still be an
adapter implementation detail; do not invent a cf Pages Functions build
command or silently discard function routing.
4. Scripts
| Before | After |
|---|
wrangler pages dev <dir> | cf dev after reviewed migration |
wrangler pages deploy <dir> | cf deploy (needs approval) |
Framework commands (astro dev, next dev) stay as they are. If the framework
has a Cloudflare adapter that supports Workers, use its documented setup.
5. Validate locally
- Build with the project's command.
- Run
/cloudflare-preflight.
cf deploy --dry-run and read its output for the asset count, the
entry file and bindings.
cf dev, then request the routes that the old site served,
including a missing path, an SPA route if applicable, and one Function route.
6. Cutover is the user's call
Deployment, custom-domain changes and deleting the Pages project are
account-level actions. Follow cloudflare-deploy: show the plan and wait for a
yes. Things to tell the user before cutover:
- Preview deployments, branch aliases and the
*.pages.dev hostname do not
carry over automatically; Workers Builds and workers.dev work differently.
- Custom domains must be attached to the Worker, and that moves traffic.
- Keep the Pages project until the Worker is verified; do not delete it.
Done means
The config converts, a dry run succeeds, cf dev serves the expected
routes, and the report lists what still needs the user (dashboard-only bindings,
domains, cutover).
CLI migration: https://developers.cloudflare.com/cf/wrangler/migrate/.