A step-by-step walkthrough for publishing a static site on Cloudflare Workers with Wrangler, static assets and automatic deploys from GitHub.
By GetSkillary Editorial · Updated
Cloudflare Workers can serve a static site directly from Cloudflare's network using its static assets feature, and you can add server-side code later without changing platforms. This tutorial takes a site that builds to a dist folder, configures it for Workers, deploys it from the command line, and then connects a GitHub repository so that every push deploys automatically.
What you need
A Cloudflare account (the free plan is sufficient for this tutorial)
Node.js installed locally, in a currently supported LTS version
A site that builds to static files, or an empty folder to start from
If you are starting fresh, the create-cloudflare tool scaffolds a project, installs Wrangler (the Workers command-line tool) and writes a configuration file for you:
npm create cloudflare@latest
The interactive prompts let you choose a framework starter or a simple static site, and decide whether to deploy immediately. You can decline deployment for now and follow the rest of this tutorial.
If you already have a project, install Wrangler as a development dependency instead:
npm install --save-dev wrangler
Step 2: Configure static assets
Wrangler reads its settings from a configuration file at the project root. Create wrangler.jsonc (or edit the one the scaffolding tool generated) so it points at your build output:
The Worker's name, used in the default workers.dev URL and the dashboard
compatibility_date
Pins the runtime behaviour to a specific date so future changes do not break your site
assets.directory
The folder of built files that Workers will serve
With only these fields and no main entry, the Worker serves files from dist without any server code. Requests for /about/ resolve to dist/about/index.html by default.
If your site is a single-page application that handles routing in the browser, add a not-found rule so unknown paths return index.html:
For a multi-page site with a custom error page, use "404-page" instead, and place a 404.html file in the output folder.
Step 3: Build and preview locally
Run your site's build so that dist contains the final files, then start the local development server:
npm run build
npx wrangler dev
Wrangler serves the site on a local port using the same runtime as production, so routing and asset handling behave as they will after deployment. Check navigation, missing pages and any client-side routes before moving on.
Step 4: Deploy from the command line
Deploy with:
npx wrangler deploy
The first time, Wrangler opens a browser window to authorise access to your Cloudflare account. You can also run npx wrangler login beforehand. When the deploy finishes, Wrangler prints the site's workers.dev URL. Only files that changed since the previous deploy are uploaded.
It is convenient to add a script to package.json so building and deploying is one command:
Manual deploys work, but most teams want each push to the main branch to go live and each pull request to get a preview. Push the project to a GitHub repository first, making sure dist and node_modules are in .gitignore so builds happen in CI rather than being committed.
In the Cloudflare dashboard, open your Worker's settings and connect it to the GitHub repository using the Workers Builds integration. You will be asked to authorise the Cloudflare GitHub app and then set:
The production branch, usually main
The build command, for example npm run build
The deploy command, typically npx wrangler deploy
After that, pushes to the production branch build and deploy automatically, and builds for other branches can produce preview versions. The name in wrangler.jsonc must match the Worker you connect, otherwise the build will fail.
If you prefer to keep CI in GitHub, an alternative is a GitHub Actions workflow that runs the build and wrangler deploy with a Cloudflare API token stored as a repository secret. Scope that token to the minimum permissions needed for Workers deployments.
Step 6: Add a custom domain
To serve the site on your own domain, the domain must be added to your Cloudflare account. Then either attach it in the dashboard under the Worker's domains settings, or declare it in configuration:
Run npx wrangler deploy again, and Cloudflare creates the DNS record and certificate automatically.
Adding server-side logic later
One reason to host a static site on Workers rather than a pure static host is that you can add code when you need it, such as a form handler, an API route or redirects. Add a main entry pointing at a script, and optionally an ASSETS binding so your code can fall back to static files:
By default, requests that match a static file are served directly, and everything else reaches your Worker code.
Troubleshooting
Symptom
Likely cause
Deploy succeeds but pages are blank or 404
assets.directory points to the wrong folder, or the build did not run
Client-side routes 404 on refresh
not_found_handling is not set to single-page-application
Git build fails immediately
Worker name in config does not match the connected Worker
Old content appears after deploy
Browser cache; check with a private window or hard refresh
Summary
A static site on Workers needs a small configuration file, a build folder and two commands: npx wrangler dev to preview and npx wrangler deploy to publish. Connecting GitHub adds automatic production and preview deploys, and the same project can grow into a full application without migrating. See the Cloudflare Workers and GitHub profiles, or compare with Vercel.
Six tools with genuinely useful free or open-source options that let a solo founder plan, build, launch, measure and get paid before spending on software.
Connect an MCP-capable client such as Claude, Cursor or Codex to the public GetSkillary MCP server to search, inspect and install reusable agent skills.
Our picks for AI tools that help developers write, review, debug and maintain code, from AI-native editors to error monitoring with AI-assisted triage.