Files
website-enchun-mgr/.opencode/skills/astro-cloudflare-deploy/SKILL.md
pkupuk ad8e2e313e chore(agent): configure AI agents and tools
Add configuration for BMad, Claude, OpenCode, and other AI agent tools and workflows.
2026-02-11 11:51:23 +08:00

8.6 KiB

name, description
name description
astro-cloudflare-deploy 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:

# 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:

# 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):

import { defineConfig } from 'astro/config';

export default defineConfig({
  output: 'static',
});
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

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:

{
  "$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:

/// <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:

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

Step 6: Deploy

Local Development

# 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

# 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:

{
  "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:

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

Environment Variables

Non-Sensitive Variables

Define in wrangler.jsonc:

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

Sensitive Secrets

# 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):

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