Skip to main content

Overview

Server-Side Rendering (SSR) allows you to generate pages dynamically on each request using Vercel Edge Functions. This enables real-time data, personalized content, and access to request context like headers and geolocation.
SSR pages are executed at the edge, close to your users, providing fast response times while maintaining dynamic capabilities.

Enabling SSR

To enable SSR for a page, set prerender to false in the page’s frontmatter:
src/pages/ssr.astro
---
import Layout from '@/layouts/Layout.astro'

export const prerender = false

const time = new Date().toLocaleTimeString()
---

<Layout
  seo={{
    title: 'Server-Side Rendering (SSR)',
    description: 'A page that uses server-side rendering (through Vercel Edge Functions)',
  }}>
  <section>
    <hgroup>
      <h2>Server-Side Rendering (SSR)</h2>
      <p>A page that uses server-side rendering (through Vercel Edge Functions)</p>
    </hgroup>

    <h1>{time}</h1>

    <a href="/ssr">Refresh</a>
  </section>
</Layout>

Accessing Request Headers

SSR pages have access to the full request context, including headers. This is useful for personalization based on geolocation, user agent, or custom headers:
src/pages/index.astro
---
export const prerender = false

const ip = Astro.request.headers.get('x-real-ip')
const city = decodeURIComponent(Astro.request.headers.get('x-vercel-ip-city')!)
---

<Layout>
  <main>
    <h1>Astro in <span class="text-gradient">Vercel</span></h1>
    <div class="banner">
      <p>Your city<br /><strong>{city}</strong></p>
      <p>Your IP address<br /><strong>{ip}</strong></p>
    </div>
  </main>
</Layout>

Available Request Headers

Vercel Edge Network Headers

  • x-real-ip - The client’s IP address
  • x-vercel-ip-city - The city of the client
  • x-vercel-ip-country - The country code of the client
  • x-vercel-ip-latitude - The latitude of the client
  • x-vercel-ip-longitude - The longitude of the client

Performance Benefits

SSR pages run on Vercel’s Edge Network, which means:
  • Execution close to users worldwide
  • Low latency responses
  • Global distribution without additional configuration

Configuration

SSR is enabled in your Astro config with the Vercel adapter:
astro.config.mjs
import vercel from '@astrojs/vercel'
import { defineConfig } from 'astro/config'

export default defineConfig({
  output: 'server',
  adapter: vercel({
    edgeMiddleware: true,
  }),
})
You can mix static and SSR pages in the same project. Pages with prerender: false will use SSR, while others remain static.

SSR with Caching

You can combine SSR with cache-control headers to cache responses at the edge while still regenerating them server-side. This provides a balance between dynamic content and performance:
src/pages/ssr-with-swr-caching.astro
---
export const prerender = false

// Set cache headers for stale-while-revalidate
Astro.response.headers.set('Cache-Control', 's-maxage=10, stale-while-revalidate')

const time = new Date().toLocaleTimeString()
---

<Layout>
  <h1>{time}</h1>
  <p>This page is cached for 10 seconds, then revalidated in the background</p>
</Layout>
The s-maxage=10 directive caches the response for 10 seconds, while stale-while-revalidate allows serving stale content while fetching fresh data in the background.

Use Cases

  • Personalization: Display content based on user location, preferences, or authentication
  • Real-time Data: Show live prices, availability, or status updates
  • A/B Testing: Serve different variants based on request parameters
  • Authentication: Check session cookies and protect routes
  • Dynamic API Responses: Create endpoints that return fresh data on each request

Next Steps

ISR

Combine static generation with on-demand revalidation

Edge Functions

Build API endpoints with Edge Functions

Build docs developers (and LLMs) love