install
source · Clone the upstream repo
git clone https://github.com/Intense-Visions/harness-engineering
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/claude-code/astro-deployment-config" ~/.claude/skills/intense-visions-harness-engineering-astro-deployment-config-72659c && rm -rf "$T"
manifest:
agents/skills/claude-code/astro-deployment-config/SKILL.mdsource content
Astro Deployment Configuration
Configure adapters, environment variables, and build output for deploying Astro to Vercel, Node.js, Cloudflare, and Netlify.
When to Use
- You are deploying an Astro project for the first time and need to choose and configure an adapter
- You are switching deployment targets and need to change the adapter and output format
- You need to manage environment variables correctly across build time and runtime
- You are debugging a deployment where pages work locally but fail in production
- You need to configure custom headers, redirects, or asset CDN behavior in the deployment target
Instructions
- Install the adapter for your target platform. Each adapter configures Astro's SSR output for that runtime:
# 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
- Configure the adapter in
: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' });
- Manage environment variables using
. Astro follows Vite's env convention:import.meta.env
// 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
- Set environment variables in
files (never commit secrets):.env
# .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
- Configure static deployments (no adapter needed) for fully static sites:
// 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).
- Configure redirects and headers directly in
for static deployments:astro.config.mjs
export default defineConfig({ redirects: { '/old-blog': '/blog', '/old-blog/[slug]': '/blog/[slug]', }, });
For SSR deployments, platform-specific config files take precedence:
- Vercel:
(headers, rewrites)vercel.json - Netlify:
(headers, redirects, functions)netlify.toml - Cloudflare:
+wrangler.toml
/_headers
files_redirects
- Set
insite
— it is required for canonical URLs, sitemaps, and theastro.config.mjs
env variable:SITE
export default defineConfig({ site: 'https://www.example.com', // must be the full URL including protocol });
- For Node.js adapter deployments, start the server with the generated entry point:
# 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
Details
Adapter selection guide:
| Platform | Adapter | Notes |
|---|---|---|
| Vercel | | Best DX; automatic image optimization |
| Vercel Edge | | No Node.js built-ins; lower latency |
| Netlify | | Functions + Edge Functions |
| Cloudflare Pages | | Workers runtime; no Node.js fs module |
| AWS Lambda | + custom wrapper | Requires additional glue |
| Docker / VPS | standalone | Full control; bring your own process manager |
| GitHub Pages | none (static) | Free; limited to |
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:
- SSG: env vars are consumed at build time — they are baked into the static HTML. Changing a public env var requires a rebuild.
- SSR: env vars are consumed at request time — update them in the platform dashboard without a rebuild.
vars in SSG are only available in the build process andSECRET_*
. They are never included in client bundles.getStaticPaths()
path configuration:base
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:
— build output rootdist/
— static pages (SSG)dist/index.html
— hashed JS/CSS chunksdist/_astro/
— SSR entry point and chunks (when using an adapter)dist/server/
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.
Source
https://docs.astro.build/en/guides/deploy
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.