> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/withastro/astro/llms.txt
> Use this file to discover all available pages before exploring further.

# SSR Adapters

> Deploy Astro with server-side rendering using Node, Vercel, Netlify, Cloudflare, and Deno adapters

SSR adapters allow you to deploy your Astro site with server-side rendering (SSR) to various hosting platforms. Each adapter configures your output to match the requirements of a specific deployment target.

## When to Use Adapters

You need an adapter when:

* Using `output: 'server'` or `output: 'hybrid'` mode
* Implementing on-demand rendering for dynamic routes
* Using server endpoints and API routes
* Deploying to a platform that requires a specific output format

For static sites (`output: 'static'`), you don't need an adapter.

## Available Adapters

<CardGroup cols={2}>
  <Card title="Node" icon="node">
    Deploy to any Node.js host
  </Card>

  <Card title="Vercel" icon="vercel">
    Deploy to Vercel with serverless or edge functions
  </Card>

  <Card title="Netlify" icon="netlify">
    Deploy to Netlify with serverless functions
  </Card>

  <Card title="Cloudflare" icon="cloudflare">
    Deploy to Cloudflare Pages or Workers
  </Card>

  <Card title="Deno">
    Deploy to Deno Deploy
  </Card>
</CardGroup>

## Node

The Node adapter allows you to deploy your SSR site to any Node.js environment.

### Installation

```bash theme={null}
npx astro add node
```

Or manually:

```bash theme={null}
npm install @astrojs/node
```

### Configuration

```js title="astro.config.mjs" theme={null}
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({
    mode: 'standalone',
  }),
});
```

### Options

```ts theme={null}
node({
  // Mode: 'middleware' or 'standalone'
  mode: 'standalone',
})
```

#### Standalone Mode

Creates a server that starts when the entry module is run:

```js title="astro.config.mjs" theme={null}
export default defineConfig({
  output: 'server',
  adapter: node({
    mode: 'standalone',
  }),
});
```

Start the server:

```bash theme={null}
node ./dist/server/entry.mjs
```

#### Middleware Mode

Exports the handler for use with your own HTTP server:

```js title="astro.config.mjs" theme={null}
export default defineConfig({
  output: 'server',
  adapter: node({
    mode: 'middleware',
  }),
});
```

Use with your own server:

```js title="server.mjs" theme={null}
import express from 'express';
import { handler as ssrHandler } from './dist/server/entry.mjs';

const app = express();

// Serve static files
app.use(express.static('dist/client/'));

// Use the Astro handler
app.use(ssrHandler);

app.listen(8080);
```

### Deployment

Build your project and start the server:

```bash theme={null}
npm run build
node ./dist/server/entry.mjs
```

Or with a custom port:

```bash theme={null}
HOST=0.0.0.0 PORT=3000 node ./dist/server/entry.mjs
```

## Vercel

The Vercel adapter deploys your site to Vercel with serverless or edge functions.

### Installation

```bash theme={null}
npx astro add vercel
```

### Configuration

```js title="astro.config.mjs" theme={null}
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
  output: 'server',
  adapter: vercel(),
});
```

### Options

```ts theme={null}
vercel({
  // Enable Web Analytics
  webAnalytics: {
    enabled: true,
  },
  
  // Enable Speed Insights
  speedInsights: {
    enabled: true,
  },
  
  // Enable Image Optimization
  imageService: true,
  
  // ISR configuration
  isr: {
    expiration: 60,
    exclude: ['/api/*'],
  },
  
  // Include files in deployment
  includeFiles: ['./data/config.json'],
  
  // Maximum duration for serverless functions (seconds)
  maxDuration: 30,
})
```

### Edge Functions

Use Vercel Edge Functions instead of serverless:

```js title="astro.config.mjs" theme={null}
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/edge';

export default defineConfig({
  output: 'server',
  adapter: vercel(),
});
```

### Per-Route Configuration

Set configuration per route using route export:

```astro title="src/pages/api/cached.astro" theme={null}
---
export const prerender = false;
export const config = {
  runtime: 'edge',
};

export async function GET() {
  return new Response('Hello from edge!');
}
---
```

### Image Optimization

Enable Vercel's Image Optimization:

```js title="astro.config.mjs" theme={null}
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
  output: 'server',
  adapter: vercel({
    imageService: true,
  }),
});
```

### Incremental Static Regeneration (ISR)

```js title="astro.config.mjs" theme={null}
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
  output: 'hybrid',
  adapter: vercel({
    isr: {
      // Cache pages for 60 seconds
      expiration: 60,
    },
  }),
});
```

## Netlify

The Netlify adapter deploys your site to Netlify with serverless functions.

### Installation

```bash theme={null}
npx astro add netlify
```

### Configuration

```js title="astro.config.mjs" theme={null}
import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify';

export default defineConfig({
  output: 'server',
  adapter: netlify(),
});
```

### Options

```ts theme={null}
netlify({
  // Use Edge Functions
  edgeMiddleware: false,
  
  // Cache on-demand rendered pages
  cacheOnDemandPages: true,
  
  // Builders for DPR (Distributed Persistent Rendering)
  builders: false,
})
```

### Edge Functions

Use Netlify Edge Functions:

```js title="astro.config.mjs" theme={null}
import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify';

export default defineConfig({
  output: 'server',
  adapter: netlify({
    edgeMiddleware: true,
  }),
});
```

### Distributed Persistent Rendering (DPR)

Cache rendered pages at the edge:

```js title="astro.config.mjs" theme={null}
import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify';

export default defineConfig({
  output: 'hybrid',
  adapter: netlify({
    cacheOnDemandPages: true,
  }),
});
```

Set cache headers per page:

```astro title="src/pages/products/[id].astro" theme={null}
---
export const prerender = false;

Astro.response.headers.set(
  'CDN-Cache-Control',
  'public, max-age=3600, s-maxage=3600'
);
---
```

### Image CDN

Netlify automatically optimizes images:

```astro theme={null}
---
import { Image } from 'astro:assets';
import myImage from '../assets/my-image.png';
---

<Image src={myImage} alt="My image" />
```

## Cloudflare

The Cloudflare adapter deploys your site to Cloudflare Pages or Workers.

### Installation

```bash theme={null}
npx astro add cloudflare
```

### Configuration

```js title="astro.config.mjs" theme={null}
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  output: 'server',
  adapter: cloudflare(),
});
```

### Options

```ts theme={null}
cloudflare({
  // Mode: 'directory' (default) or 'advanced'
  mode: 'directory',
  
  // Routes configuration
  routes: {
    // Extend routes.json
    extend: {
      include: ['/custom-route'],
      exclude: ['/api/*'],
    },
  },
  
  // Image service
  imageService: 'cloudflare',
})
```

### Access Runtime APIs

Access Cloudflare runtime in your pages:

```astro title="src/pages/api/data.json.ts" theme={null}
export async function GET({ locals }) {
  const { runtime } = locals;
  
  // Access KV namespace
  const value = await runtime.env.MY_KV.get('key');
  
  // Access D1 database
  const result = await runtime.env.DB.prepare(
    'SELECT * FROM users WHERE id = ?'
  ).bind(1).all();
  
  return new Response(JSON.stringify({ value, result }));
}
```

### Wrangler Configuration

Configure Cloudflare resources in `wrangler.toml`:

```toml title="wrangler.toml" theme={null}
name = "my-astro-app"
compatibility_date = "2024-03-15"

[[kv_namespaces]]
binding = "MY_KV"
id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
```

### Cloudflare Pages Functions

For advanced use cases, use directory mode:

```js title="astro.config.mjs" theme={null}
export default defineConfig({
  output: 'server',
  adapter: cloudflare({ mode: 'directory' }),
});
```

Add custom functions in `functions/` directory.

## Deno

The Deno adapter allows you to deploy to Deno Deploy.

### Installation

```bash theme={null}
npx astro add deno
```

### Configuration

```js title="astro.config.mjs" theme={null}
import { defineConfig } from 'astro/config';
import deno from '@astrojs/deno';

export default defineConfig({
  output: 'server',
  adapter: deno(),
});
```

### Deployment

Deploy using the Deno CLI:

```bash theme={null}
deno deploy --project=my-project ./dist/server/entry.mjs
```

Or connect your GitHub repository to Deno Deploy for automatic deployments.

## Choosing Output Mode

Adapters work with different output modes:

### Server Mode

All pages rendered on-demand:

```js title="astro.config.mjs" theme={null}
export default defineConfig({
  output: 'server',
  adapter: node(),
});
```

### Hybrid Mode

Pages are static by default, opt-in to SSR:

```js title="astro.config.mjs" theme={null}
export default defineConfig({
  output: 'hybrid',
  adapter: vercel(),
});
```

Opt-in to SSR per page:

```astro title="src/pages/dynamic.astro" theme={null}
---
export const prerender = false;
---
```

### Static Mode

All pages pre-rendered (no adapter needed):

```js title="astro.config.mjs" theme={null}
export default defineConfig({
  output: 'static',
  // No adapter needed
});
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Server Endpoints" href="/concepts/routing">
    Create API endpoints with server-side logic
  </Card>

  <Card title="On-Demand Rendering" href="/features/ssr-and-ssg">
    Learn about server-side rendering in Astro
  </Card>
</CardGroup>
