Freeframe

How to Move a Site from Cloudflare Pages to Workers

Cloudflare now tells new projects to use Workers. Move a static site from Pages with one Wrangler file, keep your 404 page and switch the domain over safely.

· 7 min read

To move a static site from Cloudflare Pages to Workers, add a small wrangler.jsonc file that points assets.directory at your site folder, set not_found_handling to "404-page" so your 404.html still works, deploy with npx wrangler deploy (or connect the repository to Workers Builds), check the new workers.dev address, then move your custom domain across and delete the old Pages project. For a plain HTML, Astro or exported Next.js site with no server code, it takes about half an hour. There's no rush: your Pages site keeps working, but this is the direction Cloudflare is heading, and the steps below cover the few things that behave differently.

Why move at all#

At the time of writing, the Cloudflare Pages docs open with a note that Workers is Cloudflare's main platform, that it "supports most Pages use cases", and that you should "start new projects with Workers". Cloudflare hasn't announced a date for switching Pages off, so an existing site isn't about to break. But new features are arriving on Workers, not Pages: the migration guide's compatibility table lists gradual deployments, Workers Logs, source maps and cron triggers as Workers-only. Just this week the changelog added the option to pin your npm version in Workers Builds with the packageManager field in package.json.

The cost doesn't change for a static site. Cloudflare's billing page for static assets says "requests to static assets are free and unlimited", exactly as on Pages. The free plan limits at the time of writing are 20,000 files per deployment and 25 MiB per file, the same figures we quoted for Pages in How to Host a Static Website for Free. Builds on the free plan get 3,000 build minutes a month, one build at a time, with a 20-minute timeout.

Check one thing before you start: your domain's DNS#

This is the only real blocker. The migration guide says that, unlike Pages, Workers doesn't support a custom domain whose nameservers aren't managed by Cloudflare. If your domain's DNS lives at your registrar and you added it to Pages with a CNAME record, you have two choices: move the domain's DNS to Cloudflare first (free, but plan it as its own job), or stay on Pages for now. If your domain already uses Cloudflare's nameservers, carry on.

If you're not sure, sign in to Cloudflare and look for the domain under Account Home. If it's listed as an active zone, its DNS is on Cloudflare.

Step 1: add a Wrangler file#

Wrangler is Cloudflare's command-line tool, and on Workers its config file replaces the settings you used to type into the Pages dashboard. Create wrangler.jsonc at the root of your project:

{
  "name": "my-site",
  "compatibility_date": "2026-10-24",
  "assets": {
    "directory": "./dist",
    "not_found_handling": "404-page"
  }
}
  • name is the Worker's name. It becomes part of the preview address (my-site.<your-subdomain>.workers.dev). If you'll deploy from Git, the name in the dashboard must match this one, or the build fails.
  • compatibility_date is required; use the day you set it up.
  • assets.directory is what Pages called the build output directory: ./dist for an Astro site, ./out for a Next.js site exported as static files, or the folder that holds index.html for plain HTML.
  • not_found_handling matters more than it looks. Pages noticed your 404.html and served it on its own. Workers doesn't guess: without this setting a missing page gets a bare 404 Not Found. With "404-page", it serves the nearest 404.html with a proper 404 status. (A single-page app would use "single-page-application" instead; a normal multi-page site shouldn't.)

There's no main entry, because a static site has no Worker script. Cloudflare serves the files directly.

Plain HTML sites: add an .assetsignore file#

Pages quietly skipped node_modules, .git and .DS_Store when it uploaded your files. Workers doesn't, so if your assets directory is the project root, as it is for our plain HTML templates, add a file called .assetsignore inside it. The migration guide suggests:

txt
**/node_modules
**/.DS_Store
**/.git

Add a line for anything else in that folder that visitors don't need, such as src or package.json.

Step 2: check your redirects, headers and URLs#

Your _redirects and _headers files keep working. The migration guide says Workers supports both natively, in the same place as before: inside the assets directory.

Clean URLs work too. The default html_handling setting is auto-trailing-slash, which serves about.html at /about and sends /about.html and /about/ there with a redirect. If your site's links and sitemap already use addresses without .html, you don't need to change anything. If you prefer every address to end in a slash, set "html_handling": "force-trailing-slash" under assets.

If your Pages project had a functions/ folder or a _worker.js file, you're running server code and the move takes more care: the migration guide covers compiling functions/ into one Worker with npx wrangler pages functions build and setting run_worker_first. Our templates don't use either.

Step 3: deploy#

You can deploy from your own computer or from Git, just as with Pages.

From your computer#

With Node.js installed, run this from the project folder:

sh
npx wrangler login
npx wrangler deploy

Wrangler uploads the folder and prints a workers.dev address. Locally, npx wrangler dev replaces wrangler pages dev, and the default port changes from 8788 to 8787.

From GitHub or GitLab#

For automatic deploys on every push, commit wrangler.jsonc, then in the Cloudflare dashboard go to Workers & Pages > Create application, choose your Git provider, pick the repository and select Save and Deploy, following the Workers Builds steps. Set the build command you used on Pages (for example pnpm build). Pushes to other branches create previews instead of updating the live site.

Then open the old Pages project's settings and turn off its automatic deployments, so the two projects don't build every commit side by side.

Step 4: test the workers.dev address#

Before any visitor sees it, open the new address and check:

  • the home page and three or four inner pages load, with styles, fonts and images;
  • an address that doesn't exist shows your own 404 page (check the status too: in the browser's developer tools, Network should show 404, not 200);
  • your redirects still go where they should;
  • forms still submit. Form services such as Formspree or Basin don't care where the site is hosted, but if yours only accepts submissions from listed domains, add the new address;
  • the headers from _headers are present, if you set any.

The launch checklist covers the rest if you want to be thorough.

Step 5: move the custom domain#

A hostname can only point at one place, and Cloudflare won't create a custom domain on a hostname that already has a CNAME record. So the switch is:

  1. In the Pages project, go to Custom domains and remove your domain. Then, on the domain's DNS Records page, delete the CNAME record that pointed it at *.pages.dev if it's still there.
  2. Straight away, open your Worker and go to Settings > Domains & Routes > Add > Custom Domain. Enter the domain and select Add Custom Domain. Cloudflare creates the DNS record for you.
  3. Repeat for www if you use it (or keep a redirect from www to the bare domain).

Do it at a quiet time of day. There's a short gap between removing the old record and the new one taking effect, and the docs don't say how long it lasts, so allow a few minutes and test from your phone on mobile data as well as your own connection. If you'd rather keep the domain in code, the custom domains page also shows the routes setting with "custom_domain": true for wrangler.jsonc.

Step 6: clean up#

Leave the Pages project for a week in case you need to roll back. Once you're happy, delete it from the dashboard or with npx wrangler pages project delete. Update your notes or README so the next person knows the site now deploys with wrangler deploy, and if you link to the hosting setup in our docs, the deploying guide has the rest of the options.

Should you move a working site today?#

If your site is static, your DNS is already on Cloudflare and you have half an hour, yes: it's a small, reversible change, and new sites should start on Workers anyway. If your domain's DNS is elsewhere, or the site runs Pages Functions you'd have to rewrite, it's fine to wait. Cloudflare hasn't set a deadline, and the steps will be the same when you're ready.

Templates for this

Studio website template preview

Studio

Business

A minimal, Swiss-style website for a small design studio, with a filterable work index, case studies and a brief estimator.

HTML + TailwindNext.jsAstroWordPress

8 pages · 153 KB

Documentation

Keep reading