Lesson 8 · Core course

Deploy the static blog to Cloudflare Workers

the built blog has a public HTTPS address, before you change any DNS.

Sign in to save progress across devices

On this page

Astro builds the site on your computer or in CI. Workers Static Assets serves the resulting files. The core site needs no server-side Astro adapter or Worker script. See Workers Static Assets for the deployment model.

1. Confirm the hosting account

Open Cloudflare and confirm the intended personal account. Choose the Free plan for this course. Your domain subscription and any paid developer plan are separate choices; check the dashboard’s actual plan rather than assuming a zone’s Free plan sets every product’s billing.

Wrangler was added to the final package.json in Lesson 06. Use the local version through pnpm:

pnpm exec wrangler login
pnpm exec wrangler whoami

Wrangler opens a browser consent flow. Read its requested permissions and confirm the account before authorizing. If you are signed into the wrong account, correct that in the browser first. The site does not need an API token committed to Git.

2. Create the static deployment configuration

Create wrangler.jsonc. Use a unique Worker name you will keep for later lessons. JSONC is JSON with optional comments.

File: wrangler.jsonc

{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "my-blog",
  "compatibility_date": "2026-10-06",
  "workers_dev": true,
  "preview_urls": false,
  "assets": {
    "directory": "./dist",
    "html_handling": "force-trailing-slash",
    "not_found_handling": "404-page"
  }
}

Keep your course date or choose the date on which you validate the deployment. A compatibility date pins runtime behavior; it is not a publication date or a scheduled release.

workers_dev: true provides a public test hostname. preview_urls: false disables Worker version preview URLs; repository branch builds are a separate setting handled in Lesson 10. The public hostname can reveal your Workers subdomain, so choose that deliberately if identity separation matters.

3. Set a few static security headers

Create public/_headers:

File: public/_headers

/*
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin
  X-Frame-Options: DENY

These apply to static asset responses through Cloudflare’s custom headers support. A future Worker API must set its own response headers. We have not added a Content Security Policy here; it requires accounting for the early inline theme script and any future sign-in/CAPTCHA scripts.

4. Validate, then deploy

pnpm verify
pnpm deploy:dry-run

The dry run should list the intended Worker and asset directory. It does not publish a site. When it is correct:

pnpm deploy

Wrangler prints the public URL, typically https://my-blog.YOUR_WORKERS_SUBDOMAIN.workers.dev. Open the actual printed URL; don’t copy the placeholder literally. The first deploy may prompt you to create or confirm your Workers subdomain.

5. Verify real responses

Replace the hostname in these commands:

curl -I https://my-blog.YOUR_WORKERS_SUBDOMAIN.workers.dev/
curl -I https://my-blog.YOUR_WORKERS_SUBDOMAIN.workers.dev/blog/hello-world/
curl -I https://my-blog.YOUR_WORKERS_SUBDOMAIN.workers.dev/this-page-does-not-exist/
curl -I https://my-blog.YOUR_WORKERS_SUBDOMAIN.workers.dev/blog/private-draft/

Expect 200 for the homepage and public article, and 404 for the missing page and unpublished draft. Visit the missing page in the browser too: a friendly message should not hide an incorrect 200 status. Check that the static response includes X-Content-Type-Options: nosniff.

Test appearance and navigation on the public URL. A successful upload is not proof that every route works. This Workers test hostname may still contain canonical links to your intended domain; it is a temporary verification address.

Checkpoint

You can open the deployed site on another device, draft URLs return 404, and real missing pages return 404. Record the Worker name, deployment version, URL, and source commit privately. DNS and email have not needed to change for this first deployment.

Commit the configuration and headers, review them, and push to GitHub. The next lessons connect the domain and then make pushes deploy automatically.