Skip to content

Deploying to Cloudflare

a9x edited this page Sep 7, 2026 · 7 revisions

StarryBio builds a static Astro site into dist/ and deploys it with Wrangler as a Cloudflare Worker using static assets. It is not a Cloudflare Pages project and does not run an Astro adapter or a custom Worker entry point.

Deploy to Cloudflare

The button opens Cloudflare’s deployment flow for a copy of this repository. Continue with the preparation steps below to give the Worker a unique name and set the correct canonical URL.

What the deployment needs

Required Why
Node.js 24.0.0+ and pnpm 12.3.4 Build the project and run its bundled Wrangler.
A Cloudflare account Wrangler publishes the static-assets Worker.
A unique Worker name under your account Identifies the deployed Worker and its default workers.dev URL.

The current StarryBio configuration needs none of the following: Cloudflare D1, KV, R2, Durable Objects, queues, bindings, runtime secrets, a database, a Worker main script, or environment variables. The content is compiled into static files at deployment time.

Prepare the project

  1. Install dependencies and make your site configuration changes.

    pnpm install
    pnpm dev
  2. Change the Worker name in wrangler.jsonc before the first deployment. The repository starter name is starry-bio and must not be shared unintentionally with another site in your account.

    {
      "$schema": "./node_modules/wrangler/config-schema.json",
      "name": "my-links-site",
      "compatibility_date": "2026-08-24",
      "send_metrics": false,
      "assets": {
        "directory": "./dist",
        "not_found_handling": "404-page",
      },
    }

    Keep assets.directory pointing at ./dist: Astro writes the final deployable files there. Keep not_found_handling as 404-page to serve StarryBio’s custom 404.html instead of treating unknown routes as a single-page application.

  3. Set the public metadata URL if you already know your production domain. This makes canonical and social-image URLs correct after the domain is connected.

    seo: {
      canonicalUrl: 'https://links.example.com',
      image: '/og.png',
    },

    If you do not yet own a domain, deploy first, then set this after choosing the final URL. Do not leave a previous owner’s canonical domain in a fork.

Authenticate Wrangler

Run the bundled Wrangler rather than installing a separate global copy:

pnpm exec wrangler login
pnpm exec wrangler whoami

Complete the browser authorization that wrangler login opens. whoami should report the Cloudflare account that is meant to own this site. In CI, use Cloudflare’s supported non-interactive authentication rather than committing credentials; StarryBio itself has no required secret variables.

Build and preview before publishing

pnpm validate
pnpm build
pnpm preview:cloudflare

pnpm preview:cloudflare first builds and then runs wrangler dev. It is useful for checking the actual dist/ output, _headers policy, generated QR/vCard assets, cache paths, and 404.html behavior before production. It does not publish the site. The shorter pnpm preview command is now a provider-neutral Astro preview.

Check at least:

  1. The profile, links, status dialog, and announcement behave as expected.
  2. A nonexistent path renders the 404 page.
  3. Generated downloads exist only when enabled.
  4. The browser console has no asset or CSP errors.

Publish

pnpm deploy

This remains a backwards-compatible alias for pnpm deploy:cloudflare, which runs pnpm build && wrangler deploy. Wrangler uploads the completed dist/ directory according to wrangler.jsonc and prints the resulting deployment information. With no custom domain or route configured, Cloudflare provides the Worker’s workers.dev address when that account feature is enabled.

Open the printed URL and repeat the production checks. In particular, inspect the browser page source or developer tools if a public analytics script is enabled; build success alone does not prove the third party is accepting events.

What gets deployed

config/starrybio.config.ts ── build scripts ──┐
public/ ──────────────────────────────────────┼─→ dist/ ─→ Cloudflare static assets
src/ ─ Astro compilation ─────────────────────┘

pnpm headers generates public/_headers from the selected analytics configuration; it is included in the static output and controls the deployed CSP, cache behavior, and browser security headers. Public assets use the configured static cache rules; hashed Astro assets have a one-year immutable cache rule. See Security and Privacy.

The generated Simple Icon directory, QR code, OG image, and vCard may be ignored by Git but are created before build and included in dist/ when enabled. See Assets and Generated Downloads.

Optional version-controlled custom domain

For a normal personal site, adding a custom domain in the Cloudflare dashboard is often simpler; follow Domains and DNS. If you deliberately want the custom domain in version control, add a Custom Domain route to wrangler.jsonc:

{
  "name": "my-links-site",
  "routes": [
    {
      "pattern": "links.example.com",
      "custom_domain": true,
    },
  ],
  "assets": {
    "directory": "./dist",
    "not_found_handling": "404-page",
  },
}

This requires an active Cloudflare zone for the domain and a hostname that does not already have a conflicting CNAME record. A Cloudflare Custom Domain maps all paths of that hostname to the Worker and Cloudflare provisions its DNS record and certificate. Do not configure the same hostname as both a custom domain and a normal Worker route.

Deployment failure checklist

  • Authentication problem: run pnpm exec wrangler whoami and sign in to the correct account.
  • Wrong or reused Worker name: edit wrangler.jsonc, then deploy again.
  • Build failure: run pnpm validate and follow its exact configuration/asset path.
  • A missing generated download: run pnpm build, then check whether its generator has enabled: true.
  • Domain already configured: resolve the DNS/route conflict described in Domains and DNS.

For more detailed symptoms, use Troubleshooting. For an existing site’s release and rollback workflow, use Operations and Updates.

Clone this wiki locally