# 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 <version-id>
   ```

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)
