Hybrid Rendering
Mix static and server-rendered pages in a single Astro project — each page picks its own rendering strategy.
What is Hybrid Rendering?
Hybrid Rendering lets you choose a per-page rendering strategy inside a single
Astro project. Set output: 'server' globally and opt individual pages out to
static pre-rendering with export const prerender = true — or set output: 'static'
globally and opt pages in to SSR with export const prerender = false.
The result: CDN-speed performance for marketing pages, live data for dashboards, all from one codebase.
In hybrid mode, each page chooses its own rendering strategy. Static pages are pre-built for maximum speed; SSR pages are rendered fresh on every request for live data.
- ✓ Built once, served from CDN
- ✓ Zero server cost per request
- ✓ Great for: blog, docs, landing
- ✗ Stale until next build
- ✓ Fresh data on every request
- ✓ Can read cookies / headers
- ✓ Great for: dashboards, auth, APIs
- ✗ Slightly slower (server roundtrip)
This demo component
Reload the page — the time above updates, proving this is SSR, not a static snapshot.
Configuration
Choose your global default in astro.config.mjs
output: 'server'→ SSR by default, opt-in to static per pageoutput: 'static'→ static by default, opt-in to SSR per pageoutput: 'hybrid'→ same asserver(legacy alias kept for clarity)
// astro.config.mjs
import { defineConfig } from 'astro/config'
import node from '@astrojs/node'
export default defineConfig({
output: 'server',
adapter: node({ mode: 'standalone' }),
}) Opt a page into static pre-rendering
Add one line to the frontmatter of any page you want to be static:
---
// src/pages/about.astro
export const prerender = true // ← built once at deploy time
---
<h1>About Us</h1> Keep other pages as SSR
Pages without prerender = true (or with prerender = false) render on every request.
---
// src/pages/dashboard.astro
// No prerender export → uses project default (SSR)
import { getUser } from '../lib/auth'
const user = await getUser(Astro.cookies.get('session')?.value)
if (!user) return Astro.redirect('/login')
---
<h1>Hello, {user.name}</h1> When to use each mode
| Page type | Mode | Reason |
|---|---|---|
| Landing page | Static | Maximum speed, CDN cached |
| Blog post | Static | Content rarely changes |
| Docs article | Static | Best SEO + speed |
| User dashboard | SSR | Needs auth + live data |
| Admin panel | SSR | Sensitive, always fresh |
| Checkout page | SSR | Live cart + payment |
| API endpoint | SSR | Always live |
You can mix page-level prerender with server islands — a static page
can still include server:defer components for live data in specific spots.
Static pages are built to HTML files and can be served directly from Nginx without hitting your Node server at all. This dramatically reduces server load.