---
name: astro-cloudflare-deploy
description: Deploy Astro 6 frontend applications to Cloudflare Workers. This skill should be used when deploying an Astro project to Cloudflare, whether as a static site, hybrid rendering, or full SSR. Handles setup of @astrojs/cloudflare adapter, wrangler.jsonc configuration, environment variables, and CI/CD deployment workflows.
---

# Astro 6 to Cloudflare Workers Deployment

## Overview

This skill provides a complete workflow for deploying Astro 6 applications to Cloudflare Workers. It covers static sites, hybrid rendering, and full SSR deployments using the official @astrojs/cloudflare adapter.

**Key Requirements:**
- Astro 6.x (requires Node.js 22.12.0+)
- @astrojs/cloudflare adapter v13+
- Wrangler CLI v4+

## Deployment Decision Tree

First, determine the deployment mode based on project requirements:

```
┌─────────────────────────────────────────────────────────────────┐
│                    DEPLOYMENT MODE DECISION                      │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  1. Static Site?                                                 │
│     └─ Marketing sites, blogs, documentation                    │
│     └─ No server-side rendering needed                          │
│     └─ Go to: Static Deployment                                 │
│                                                                  │
│  2. Mixed static + dynamic pages?                               │
│     └─ Some pages need SSR (dashboard, user-specific content)  │
│     └─ Most pages are static                                    │
│     └─ Go to: Hybrid Deployment                                 │
│                                                                  │
│  3. All pages need server rendering?                            │
│     └─ Web app with authentication, dynamic content            │
│     └─ Real-time data on all pages                             │
│     └─ Go to: Full SSR Deployment                              │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
```

## Step 1: Verify Prerequisites

Before deployment, verify the following:

```bash
# Check Node.js version (must be 22.12.0+)
node --version

# If Node.js is outdated, upgrade to v22 LTS or latest
# Check Astro version
npm list astro

# If upgrading to Astro 6:
npx @astrojs/upgrade@beta
```

**Important:** Astro 6 requires Node.js 22.12.0 or higher. Verify both local and CI/CD environments meet this requirement.

## Step 2: Install Dependencies

Install the Cloudflare adapter and Wrangler:

```bash
# Automated installation (recommended)
npx astro add cloudflare

# Manual installation
npm install @astrojs/cloudflare wrangler --save-dev
```

The automated command will:
- Install `@astrojs/cloudflare`
- Update `astro.config.mjs` with the adapter
- Prompt for deployment mode selection

## Step 3: Configure Astro

Edit `astro.config.mjs` or `astro.config.ts` based on the deployment mode.

### Static Deployment

For purely static sites (no adapter needed):

```javascript
import { defineConfig } from 'astro/config';

export default defineConfig({
  output: 'static',
});
```

### Hybrid Deployment (Recommended for Most Projects)

```javascript
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  output: 'hybrid',
  adapter: cloudflare({
    imageService: 'passthrough',  // or 'compile' for optimization
    platformProxy: {
      enabled: true,
      configPath: './wrangler.jsonc',
    },
  }),
});
```

Mark specific pages for SSR with `export const prerender = false`.

### Full SSR Deployment

```javascript
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  output: 'server',
  adapter: cloudflare({
    mode: 'directory',  // or 'standalone' for single worker
    imageService: 'passthrough',
    platformProxy: {
      enabled: true,
      configPath: './wrangler.jsonc',
    },
  }),
});
```

## Step 4: Create wrangler.jsonc

Cloudflare now recommends `wrangler.jsonc` (JSON with comments) over `wrangler.toml`. Use the template in `assets/wrangler.jsonc` as a starting point.

Key configuration:

```jsonc
{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "name": "your-app-name",
  "compatibility_date": "2025-01-19",
  "assets": {
    "directory": "./dist",
    "binding": "ASSETS"
  }
}
```

**Copy the template from:**
```
assets/wrangler-static.jsonc  - For static sites
assets/wrangler-hybrid.jsonc  - For hybrid rendering
assets/wrangler-ssr.jsonc     - For full SSR
```

## Step 5: Configure TypeScript Types

For TypeScript projects, create or update `src/env.d.ts`:

```typescript
/// <reference path="../.astro/types.d.ts" />

interface Env {
  // Add your Cloudflare bindings here
  MY_KV_NAMESPACE: KVNamespace;
  MY_D1_DATABASE: D1Database;
  API_URL: string;
}

type Runtime = import('@astrojs/cloudflare').Runtime<Env>;

declare namespace App {
  interface Locals extends Runtime {}
}
```

Update `tsconfig.json`:

```json
{
  "compilerOptions": {
    "types": ["@cloudflare/workers-types"]
  }
}
```

## Step 6: Deploy

### Local Development

```bash
# Build the project
npm run build

# Local development with Wrangler
npx wrangler dev

# Remote development (test against production environment)
npx wrangler dev --remote
```

### Production Deployment

```bash
# Deploy to Cloudflare Workers
npx wrangler deploy

# Deploy to specific environment
npx wrangler deploy --env staging
```

### Using GitHub Actions

See `assets/github-actions-deploy.yml` for a complete CI/CD workflow template.

## Step 7: Configure Bindings (Optional)

For advanced features, add bindings in `wrangler.jsonc`:

```jsonc
{
  "kv_namespaces": [
    { "binding": "MY_KV", "id": "your-kv-id" }
  ],
  "d1_databases": [
    { "binding": "DB", "database_name": "my-db", "database_id": "your-d1-id" }
  ],
  "r2_buckets": [
    { "binding": "BUCKET", "bucket_name": "my-bucket" }
  ]
}
```

Access bindings in Astro code:

```javascript
---
const kv = Astro.locals.runtime.env.MY_KV;
const value = await kv.get("key");
---
```

## Environment Variables

### Non-Sensitive Variables

Define in `wrangler.jsonc`:

```jsonc
{
  "vars": {
    "API_URL": "https://api.example.com",
    "ENVIRONMENT": "production"
  }
}
```

### Sensitive Secrets

```bash
# Add a secret (encrypted, not stored in config)
npx wrangler secret put API_KEY

# Add environment-specific secret
npx wrangler secret put API_KEY --env staging

# List all secrets
npx wrangler secret list
```

### Local Development Secrets

Create `.dev.vars` (add to `.gitignore`):

```bash
API_KEY=local_dev_key
DATABASE_URL=postgresql://localhost:5432/mydb
```

## Troubleshooting

Refer to `references/troubleshooting.md` for common issues and solutions.

Common problems:

1. **"MessageChannel is not defined"** - React 19 compatibility issue
   - Solution: See troubleshooting guide

2. **Build fails with Node.js version error**
   - Solution: Upgrade to Node.js 22.12.0+

3. **Styling lost in Astro 6 beta dev mode**
   - Solution: Known bug, check GitHub issue status

4. **404 errors on deployment**
   - Solution: Check `_routes.json` configuration

## Resources

### references/
- `troubleshooting.md` - Common issues and solutions
- `configuration-guide.md` - Detailed configuration options
- `upgrade-guide.md` - Migrating from older versions

### assets/
- `wrangler-static.jsonc` - Static site configuration template
- `wrangler-hybrid.jsonc` - Hybrid rendering configuration template
- `wrangler-ssr.jsonc` - Full SSR configuration template
- `github-actions-deploy.yml` - CI/CD workflow template
- `dev.vars.example` - Local secrets template

## Official Documentation

- [Astro Cloudflare Adapter](https://docs.astro.build/en/guides/integrations-guide/cloudflare/)
- [Cloudflare Workers Documentation](https://developers.cloudflare.com/workers/)
- [Wrangler CLI Reference](https://developers.cloudflare.com/workers/wrangler/)
- [Astro 6 Beta Announcement](https://astro.build/blog/astro-6-beta/)
