Skip to content

Astro + Cloudflare

This guide will walk you through deploying an Astro project to Cloudflare Workers from scratch. Perfect for beginners!

Before starting, make sure you have:

  • Node.js (v18 or higher) or Bun installed
  • A Cloudflare account (free tier works fine)
  • Basic terminal/command line knowledge

Understanding where files go is crucial! Here’s the complete folder structure of an Astro + Cloudflare project:

  • Directorymy-astro-site/ Your project folder (root)
    • Directorysrc/ Source code (you work here)
      • Directorypages/ Your website pages
        • index.astro Homepage (/)
      • Directorycomponents/ Reusable components
      • Directorylayouts/ Page layouts
      • Directorystyles/ CSS files
    • Directorypublic/ Static files (images, fonts, etc.)
      • favicon.svg Site icon
    • Directorydist/ Built files (auto-generated)
      • _worker.js Cloudflare Worker script
      • .assetsignore Ignore file for Wrangler
    • Directorynode_modules/ Dependencies (auto-installed)
    • astro.config.mjs Root Astro configuration
    • wrangler.jsonc Root Cloudflare config
    • package.json Root Project info & scripts
    • tsconfig.json TypeScript config
    • .gitignore Git ignore file
File/FolderLocationPurpose
astro.config.mjsRootAstro + Cloudflare adapter config
wrangler.jsoncRootCloudflare deployment settings
package.jsonRootDependencies and scripts
.assetsignoredist/Tells Wrangler what to ignore
.dev.varsRootLocal environment variables
Your pagessrc/pages/Website pages you create
Static assetspublic/Images, fonts (copied as-is)

When the guide says “create in project root”, it means:

  • Directorymy-astro-site/
    • astro.config.mjs Root
    • wrangler.jsonc Root
    • package.json Root

Open your terminal and run:

Terminal window
bun create astro@latest

You’ll be asked several questions:

Where should we create your new project?
→ my-astro-site
How would you like to start your new project?
→ Choose a starter template (or "Empty" for blank project)
Install dependencies?
→ Yes
Do you plan to write TypeScript?
→ Yes (recommended)
Initialize a git repository?
→ Yes (recommended)
Terminal window
cd my-astro-site

Astro needs an adapter to work with Cloudflare Workers.

  1. Install Cloudflare Adapter

    Terminal window
    bun add @astrojs/cloudflare
  2. Install Wrangler (Cloudflare CLI)

    Wrangler is Cloudflare’s command-line tool for deployment.

    Terminal window
    bun add wrangler --dev

  1. Update Astro Config

    Open astro.config.mjs and add the Cloudflare adapter:

    astro.config.mjs
    // astro.config.mjs
    import { defineConfig } from 'astro/config';
    import cloudflare from '@astrojs/cloudflare';
    export default defineConfig({
    output: 'server', // Enable SSR
    adapter: cloudflare(),
    });
  2. Create Wrangler Configuration

    Create a file named wrangler.jsonc in your project root (same level as package.json):

    File location:

    my-astro-site/
    ├── package.json
    ├── wrangler.jsonc ← Create here
    └── astro.config.mjs
    wrangler.jsonc
    {
    "$schema": "node_modules/wrangler/config-schema.json",
    "name": "my-astro-site",
    "compatibility_date": "2025-10-13",
    "workers_dev": true,
    "assets": {
    "directory": "./dist",
    "not_found_handling": "404-page"
    }
    }

    How to create:

    Terminal window
    # Make sure you're in project root
    cd my-astro-site
    # Create the file
    touch wrangler.jsonc
    # Then open it in your editor and paste the JSON above
  3. Understanding .assetsignore File

    File location:

    my-astro-site/ ← Project root
    ├── package.json
    ├── wrangler.jsonc
    └── dist/ ← Build output folder
    ├── _worker.js
    └── .assetsignore ← Create here

    The Problem:

    • The dist/ folder is auto-generated when you run bun run build
    • It gets deleted and recreated every time you build
    • So .assetsignore needs to be recreated after each build

    Solution 1: Auto-create with deploy script

    Add this to your package.json scripts:

    package.json
    {
    "scripts": {
    "deploy": "npm run build && echo '_worker.js' > dist/.assetsignore && npx wrangler deploy"
    }
    }

    Now run: npm run deploy (or bun run deploy)

    Solution 2: Manual creation after build

    Terminal window
    # 1. Build first
    bun run build
    # 2. Create .assetsignore in dist folder
    echo "_worker.js" > dist/.assetsignore
    # 3. Deploy
    npx wrangler deploy

    File content:

    _worker.js

  1. Create Cloudflare Account

    1. Go to cloudflare.com
    2. Click Sign Up
    3. Enter your email and password
    4. Verify your email address
  2. Get Your Account ID Optional

    1. Log in to Cloudflare Dashboard
    2. Click on Workers & Pages in the sidebar
    3. Your Account ID is displayed on the right side
    4. Copy it for later (you might need it)

  1. Login to Cloudflare via Wrangler

    Run this command in your terminal:

    Terminal window
    npx wrangler login

    This will:

    1. Open your browser automatically
    2. Ask you to authorize Wrangler
    3. Click Allow to grant permissions
    4. Return to terminal - you’ll see “Successfully logged in”
  2. Verify Login

    Check if you’re logged in:

    Terminal window
    npx wrangler whoami

    You should see your account email and Account ID.


  1. Test Locally First

    Before deploying, test your site locally:

    Terminal window
    bun run dev

    Visit http://localhost:4321 to see your site.

  2. Build Your Project

    Build your Astro site for production:

    Terminal window
    bun run build

    This creates a dist folder with your built site.

  3. Deploy to Cloudflare

    Deploy your site:

    Terminal window
    npx wrangler deploy

    What happens:

    • Uploads your built files to Cloudflare
    • Creates a Worker
    • Gives you a live URL like: https://my-astro-site.YOUR-SUBDOMAIN.workers.dev
  4. Visit Your Live Site

    After deployment completes, you’ll see:

    Deployed my-astro-site triggers (5.00 sec)
    https://my-astro-site.YOUR-SUBDOMAIN.workers.dev
    Current Version ID: abc123...

    Click the URL or copy it to your browser!


Whenever you update your site:

  1. Make your changes in code

  2. Test locally

    Terminal window
    bun run dev
  3. Build for production

    Terminal window
    bun run build
  4. Deploy

    Terminal window
    npx wrangler deploy

Quick command (build + deploy in one line):

Terminal window
bun run build && npx wrangler deploy

Here’s where each config file should be:

  • Directorymy-astro-site/ PROJECT ROOT
    • astro.config.mjs 1. Astro config
    • wrangler.jsonc 2. Cloudflare config
    • package.json 3. Scripts
    • .dev.vars 4. Local env vars (optional)
    • Directorysrc/
    • Directorydist/ Generated on build
      • .assetsignore 5. Wrangler ignore

Your project needs these configuration files:

1. astro.config.mjs Location: Root

Section titled “1. astro.config.mjs ”
astro.config.mjs
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';
export default defineConfig({
output: 'server',
adapter: cloudflare(),
});
wrangler.jsonc
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-astro-site",
"compatibility_date": "2025-10-13",
"workers_dev": true,
"assets": {
"directory": "./dist",
"not_found_handling": "404-page"
}
}
_worker.js
package.json
{
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"deploy": "bun run build && echo '_worker.js' > dist/.assetsignore && npx wrangler deploy"
}
}

CommandDescription
bun run devStart local development server
bun run buildBuild project for production
bun run previewPreview production build locally
bun run deployBuild and deploy in one command
CommandDescription
npx wrangler loginLogin to Cloudflare
npx wrangler logoutLogout from Cloudflare
npx wrangler whoamiCheck current login status
npx wrangler deployDeploy to Cloudflare Workers
npx wrangler tailView live logs from your worker
npx wrangler deleteDelete your worker

Quick Deployment:

Terminal window
bun run deploy

What it does:

  1. Builds your Astro site
  2. Creates .assetsignore file (prevents _worker.js error)
  3. Deploys to Cloudflare Workers

Manual Steps (if needed):

Terminal window
# 1. Build
bun run build
# 2. Create .assetsignore
echo '_worker.js' > dist/.assetsignore
# 3. Deploy
npx wrangler deploy

Error:

In a non-interactive environment, it's necessary to set a CLOUDFLARE_API_TOKEN

Error:

Uploading a Pages _worker.js directory as an asset

Error:

Port 4321 is in use

If your app needs environment variables:

  1. Create .dev.vars File

    For local development:

    .dev.vars
    DATABASE_URL=your-database-url
    API_KEY=your-api-key
  2. Add to Cloudflare

    For production, add secrets via Wrangler:

    Terminal window
    npx wrangler secret put DATABASE_URL
    # Enter your value when prompted

    Or add in wrangler.jsonc:

    wrangler.jsonc
    {
    "vars": {
    "ENVIRONMENT": "production"
    }
    }

  1. Add Domain to Cloudflare

    1. Go to Cloudflare Dashboard
    2. Click Add Site
    3. Enter your domain
    4. Follow DNS setup instructions
  2. Add Route to Worker

    In wrangler.jsonc, add:

    wrangler.jsonc
    {
    "routes": [
    {
    "pattern": "yourdomain.com/*",
    "zone_name": "yourdomain.com"
    }
    ]
    }
  3. Deploy

    Terminal window
    npx wrangler deploy

    Your site will be available at your custom domain!



Now that your site is deployed:

  1. Add More Pages - Create new .astro files in src/pages/
  2. Customize Design - Edit your components and styles
  3. Add Features - Install Astro integrations
  4. Set Up CI/CD - Automate deployments with GitHub Actions
  5. Monitor Performance - Use Cloudflare Analytics


You’ve learned how to:

  • Install and set up Astro
  • Add Cloudflare adapter
  • Configure Wrangler
  • Authenticate with Cloudflare
  • Build and deploy your site
  • Update and redeploy
  • Troubleshoot common issues

Happy deploying!