Static vs SSR
Next.js gives you three rendering modes per page: static (SSG), server-side rendering (SSR), and incremental static regeneration (ISR). Astro starts from the opposite end — static by default, opt into SSR per route — using a simpler two-switch model: the global output option plus the per-page prerender export.
The output option
Section titled “The output option”import { defineConfig } from 'astro/config';
export default defineConfig({ // 'static' — default; build-time HTML for every page // 'server' — every page is server-rendered unless prerender=true output: 'static',});When output is 'static' (the default) Astro pre-renders every page at build time and writes static HTML files to dist/. No server process is needed — you can deploy to any CDN or static host.
Adding an SSR adapter
Section titled “Adding an SSR adapter”To use output: 'server' you must install an adapter that tells Astro how to run server-side code in your target environment.
# Choose one:npx astro add vercel # Vercel serverless functionsnpx astro add netlify # Netlify Edge Functionsnpx astro add node # Self-hosted Node.js (express/standalone)npx astro add cloudflare # Cloudflare Workers / Pages// astro.config.mjs — SSR with Vercel adapterimport { defineConfig } from 'astro/config';import vercel from '@astrojs/vercel/serverless';
export default defineConfig({ output: 'server', adapter: vercel(),});Per-page prerender export
Section titled “Per-page prerender export”With output: 'server', every page is server-rendered by default. Opt individual pages back to static HTML by exporting prerender = true.
---// This page is still pre-rendered even though output: 'server'export const prerender = true;
const title = "About us";---<h1>{title}</h1>The reverse also works: with output: 'static', mark a page as server-only with export const prerender = false.
Comparing rendering modes
Section titled “Comparing rendering modes”// Next.js rendering modes (App Router)
// Static (SSG) — default for Server Components// No special export needed; just write a Server Component.// next build pre-renders it to HTML.
// SSR — opt in per routeexport const dynamic = 'force-dynamic';
// ISR — revalidate on a scheduleexport const revalidate = 60; // seconds
// Client-side only (CSR)'use client';import { useEffect, useState } from 'react';// ...// Astro rendering modes
// astro.config.mjs// output: 'static' → all pages are pre-rendered (default)// output: 'server' → all pages are SSR by default
// Per-page overrides (works in both modes):// Pre-render this specific page:export const prerender = true;
// Server-render this specific page:export const prerender = false;
// No ISR equivalent in core Astro — use adapter-specific// options (e.g. Vercel's isr: { expiration: 60 }) in// astro.config.mjs if your adapter supports it.Dynamic routes with SSR
Section titled “Dynamic routes with SSR”When a page depends on request-time data (auth cookies, URL params, POST body), write it as an SSR page:
---export const prerender = false; // server-render this page
const session = Astro.cookies.get('session')?.value;if (!session) return Astro.redirect('/login');
const user = await fetchUser(session);---<h1>Welcome, {user.name}</h1>This is the Astro equivalent of a Next.js getServerSideProps page or a dynamic Server Component that reads cookies.
ISR in Astro
Section titled “ISR in Astro”Astro does not have a built-in ISR equivalent like Next.js revalidate. Adapter-specific options exist:
// astro.config.mjs — Vercel ISR via adapter configimport { defineConfig } from 'astro/config';import vercel from '@astrojs/vercel/serverless';
export default defineConfig({ output: 'server', adapter: vercel({ isr: { expiration: 60, // re-generate after 60 seconds }, }),});