From harness-claude
Configures Astro adapters, environment variables, and build output for deploying to Vercel, Node.js, Cloudflare, and Netlify. Use when setting up or switching deployment targets.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:astro-deployment-configThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Configure adapters, environment variables, and build output for deploying Astro to Vercel, Node.js, Cloudflare, and Netlify.
Configure adapters, environment variables, and build output for deploying Astro to Vercel, Node.js, Cloudflare, and Netlify.
# Vercel (serverless functions)
npx astro add vercel
# Vercel Edge (edge runtime — limited Node.js APIs)
# Manual: import vercel from '@astrojs/vercel/edge'
# Node.js (self-hosted server)
npx astro add node
# Cloudflare Pages
npx astro add cloudflare
# Netlify
npx astro add netlify
astro.config.mjs:// Vercel — serverless (most common)
import vercel from '@astrojs/vercel/serverless';
export default defineConfig({
output: 'server',
adapter: vercel({
webAnalytics: { enabled: true },
imageService: true, // use Vercel Image Optimization
devImageService: 'sharp', // local dev uses sharp
}),
});
// Node.js — standalone server
import node from '@astrojs/node';
export default defineConfig({
output: 'server',
adapter: node({ mode: 'standalone' }), // or 'middleware' for Express
});
// Cloudflare Pages
import cloudflare from '@astrojs/cloudflare';
export default defineConfig({
output: 'server',
adapter: cloudflare({ mode: 'directory' }), // or 'advanced'
});
import.meta.env. Astro follows Vite's env convention:// Public variables (exposed to client bundles) — must be prefixed PUBLIC_
const apiBase = import.meta.env.PUBLIC_API_BASE_URL;
// Server-only variables (never sent to client)
const dbUrl = import.meta.env.DATABASE_URL;
const secretKey = import.meta.env.SECRET_KEY;
// Built-in variables
const isDev = import.meta.env.DEV; // boolean
const isProd = import.meta.env.PROD; // boolean
const siteUrl = import.meta.env.SITE; // set in astro.config.mjs > site
const baseUrl = import.meta.env.BASE_URL; // set in astro.config.mjs > base
.env files (never commit secrets):# .env (committed — only PUBLIC_ vars)
PUBLIC_API_BASE_URL=https://api.example.com
# .env.local (gitignored — secrets)
DATABASE_URL=postgres://...
SECRET_KEY=abc123
# .env.production (committed — production public vars only)
PUBLIC_API_BASE_URL=https://api.production.com
// astro.config.mjs
export default defineConfig({
output: 'static', // default — no adapter needed
site: 'https://example.com',
base: '/docs', // if deployed to a subdirectory
build: {
assets: '_assets', // custom directory for built assets (default: '_astro')
},
});
Deploy the dist/ directory to any static host (GitHub Pages, Netlify, Cloudflare Pages in static mode, S3 + CloudFront).
astro.config.mjs for static deployments:export default defineConfig({
redirects: {
'/old-blog': '/blog',
'/old-blog/[slug]': '/blog/[slug]',
},
});
For SSR deployments, platform-specific config files take precedence:
vercel.json (headers, rewrites)netlify.toml (headers, redirects, functions)wrangler.toml + _headers / _redirects filessite in astro.config.mjs — it is required for canonical URLs, sitemaps, and the SITE env variable:export default defineConfig({
site: 'https://www.example.com', // must be the full URL including protocol
});
# Build
npx astro build
# Start (standalone mode)
node ./dist/server/entry.mjs
# With environment variables
DATABASE_URL=postgres://... node ./dist/server/entry.mjs
# Configure the host/port
HOST=0.0.0.0 PORT=3000 node ./dist/server/entry.mjs
Adapter selection guide:
| Platform | Adapter | Notes |
|---|---|---|
| Vercel | @astrojs/vercel/serverless | Best DX; automatic image optimization |
| Vercel Edge | @astrojs/vercel/edge | No Node.js built-ins; lower latency |
| Netlify | @astrojs/netlify | Functions + Edge Functions |
| Cloudflare Pages | @astrojs/cloudflare | Workers runtime; no Node.js fs module |
| AWS Lambda | @astrojs/node + custom wrapper | Requires additional glue |
| Docker / VPS | @astrojs/node standalone | Full control; bring your own process manager |
| GitHub Pages | none (static) | Free; limited to output: 'static' |
Cloudflare-specific considerations:
Cloudflare Workers do not support Node.js built-in modules (fs, path, crypto from Node.js). Use the Cloudflare-native equivalents: crypto.subtle for crypto, KV / R2 for storage. Add { mode: 'directory' } to the Cloudflare adapter when deploying to Pages (as opposed to Workers).
Environment variables at runtime vs. build time:
SECRET_* vars in SSG are only available in the build process and getStaticPaths(). They are never included in client bundles.base path configuration:
When deploying to a subdirectory (e.g., GitHub Pages project site at /repo-name/), set base: '/repo-name'. Astro prefixes all internal links, assets, and the router with this base. Access it via import.meta.env.BASE_URL.
Build output structure:
dist/ — build output rootdist/index.html — static pages (SSG)dist/_astro/ — hashed JS/CSS chunksdist/server/ — SSR entry point and chunks (when using an adapter)CI/CD patterns:
Most platforms (Vercel, Netlify, Cloudflare Pages) auto-detect Astro projects and set the build command (astro build) and output directory (dist/) automatically. For Node.js self-hosted deployments, set up a process manager (PM2, systemd) to keep the server running and restart on crash.
https://docs.astro.build/en/guides/deploy
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeDeploying Astro 6 apps — @astrojs/cloudflare (Workers, D1, KV, R2), @astrojs/vercel (Serverless/Edge, Image CDN), @astrojs/netlify (Edge Functions), @astrojs/node (standalone), ISR patterns, edge middleware, skew protection. Use for any deployment configuration.
Guides Astro rendering strategy decisions (SSG, SSR, hybrid), islands architecture with hydration directives, and content collections. Includes adapter configuration for Cloudflare and other platforms.
Guides deployment of web frameworks (Vite/React, Astro, TanStack Start, Next.js, Nuxt, SvelteKit, Remix) on Netlify, covering adapters, environment variables, and client-side routing.