# Upgrade Guide Migrating existing Astro projects to deploy on Cloudflare Workers. ## Table of Contents 1. [From Astro 5 to Astro 6](#from-astro-5-to-astro-6) 2. [From Other Platforms to Cloudflare](#from-other-platforms-to-cloudflare) 3. [Adapter Migration](#adapter-migration) 4. [Breaking Changes](#breaking-changes) --- ## From Astro 5 to Astro 6 ### Prerequisites Check Astro 6 requires: | Requirement | Minimum Version | Check Command | |-------------|-----------------|---------------| | Node.js | 22.12.0+ | `node --version` | | Astro | 6.0.0 | `npm list astro` | | Cloudflare Adapter | 13.0.0+ | `npm list @astrojs/cloudflare` | ### Upgrade Steps 1. **Backup current state:** ```bash git commit -am "Pre-upgrade commit" ``` 2. **Run automated upgrade:** ```bash npx @astrojs/upgrade@beta ``` 3. **Update adapter:** ```bash npm install @astrojs/cloudflare@beta ``` 4. **Update Node.js** if needed: ```bash # Using nvm nvm install 22 nvm use 22 # Or download from nodejs.org ``` 5. **Update CI/CD Node.js version:** ```yaml # .github/workflows/deploy.yml - uses: actions/setup-node@v4 with: node-version: '22' ``` 6. **Test locally:** ```bash npm install npm run dev npm run build npx wrangler dev ``` ### Breaking Changes #### 1. Vite 7.0 Vite has been upgraded to Vite 7.0. Check plugin compatibility: ```bash # Check for outdated plugins npm outdated # Update Vite-specific plugins npm update @vitejs/plugin-react ``` #### 2. Hybrid Output Behavior The `hybrid` output mode behavior has changed: ```javascript // Old (Astro 5) export const prerender = true; // Static // New (Astro 6) - same, but default behavior changed // Static is now the default for all pages in hybrid mode ``` #### 3. Development Server The new dev server runs on the production runtime: ```javascript // Old: Vite dev server // New: workerd runtime (same as production) // Update your code if it relied on Vite-specific behavior ``` --- ## From Other Platforms to Cloudflare ### From Vercel **Remove Vercel adapter:** ```bash npm uninstall @astrojs/vercel ``` **Install Cloudflare adapter:** ```bash npm install @astrojs/cloudflare wrangler --save-dev ``` **Update astro.config.mjs:** ```javascript // Before import vercel from '@astrojs/vercel'; export default defineConfig({ adapter: vercel(), }); // After import cloudflare from '@astrojs/cloudflare'; export default defineConfig({ adapter: cloudflare(), }); ``` **Update environment variables:** - Vercel: `process.env.VARIABLE` - Cloudflare: `Astro.locals.runtime.env.VARIABLE` or `env.VARIABLE` in endpoints ### From Netlify **Remove Netlify adapter:** ```bash npm uninstall @astrojs/netlify ``` **Install Cloudflare adapter:** ```bash npm install @astrojs/cloudflare wrangler --save-dev ``` **Update netlify.toml to wrangler.jsonc:** ```toml # netlify.toml (old) [build] command = "astro build" publish = "dist" [functions] node_bundler = "esbuild" ``` ```jsonc // wrangler.jsonc (new) { "name": "my-app", "compatibility_date": "2025-01-19", "assets": { "directory": "./dist" } } ``` ### From Node.js Server **Before (Express/Fastify server):** ```javascript // server.js import express from 'express'; app.use(express.static('dist')); app.listen(3000); ``` **After (Cloudflare Workers):** ```javascript // astro.config.mjs export default defineConfig({ output: 'server', adapter: cloudflare(), }); // Deploy npx wrangler deploy ``` --- ## Adapter Migration ### From Astro 4 to 5/6 **Old adapter syntax:** ```javascript // Astro 4 adapter: cloudflare({ functionPerRoute: true, }) ``` **New adapter syntax:** ```javascript // Astro 5/6 adapter: cloudflare({ mode: 'directory', // equivalent to functionPerRoute: true }) ``` ### Mode Migration Guide | Old Option | New Option | Notes | |------------|------------|-------| | `functionPerRoute: true` | `mode: 'directory'` | Recommended | | `functionPerRoute: false` | `mode: 'standalone'` | Single worker | --- ## Breaking Changes ### Removed APIs 1. **`Astro.locals` changes:** ```javascript // Old const env = Astro.locals.env; // New const env = Astro.locals.runtime.env; ``` 2. **Endpoint API changes:** ```javascript // Old export async function get({ locals }) { const { env } = locals; } // New export async function GET({ locals }) { const env = locals.runtime.env; } ``` ### TypeScript Changes ```typescript // Old type imports import type { Runtime } from '@astrojs/cloudflare'; // New type imports import type { Runtime } from '@astrojs/cloudflare/virtual'; // Or use the adapter export import cloudflare from '@astrojs/cloudflare'; type Runtime = typeof cloudflare.Runtime; ``` --- ## Rollback Procedures ### If Deployment Fails 1. **Keep old version deployed:** ```bash npx wrangler versions list npx wrangler versions rollback ``` 2. **Or rollback git changes:** ```bash git revert HEAD npx wrangler deploy ``` ### If Build Fails 1. **Clear cache:** ```bash rm -rf node_modules .astro dist npm install npm run build ``` 2. **Check for incompatible dependencies:** ```bash npm ls ``` 3. **Temporarily pin to previous version:** ```bash npm install astro@5 npm install @astrojs/cloudflare@12 ``` --- ## Verification Checklist After upgrading, verify: - [ ] Local dev server starts without errors - [ ] Build completes successfully - [ ] `wrangler dev` works locally - [ ] Static assets load correctly - [ ] SSR routes render properly - [ ] Environment variables are accessible - [ ] Cloudflare bindings (KV/D1/R2) work - [ ] TypeScript types are correct - [ ] CI/CD pipeline succeeds - [ ] Production deployment works --- ## Getting Help - [Astro Discord](https://astro.build/chat) - [Cloudflare Discord](https://discord.gg/cloudflaredev) - [Astro GitHub Issues](https://github.com/withastro/astro/issues)