Render on Every Request
Server-Side Rendering
Pages that read cookies, headers, or runtime data are rendered fresh on every request — slower than static, but always up to date.
What you'll learn
- Force SSR by reading `cookies()` or `headers()`
- Use fetch with the no-store cache option to opt out of caching
- Know the latency trade-off
SSR renders the page on every request. You give up SSG’s speed in exchange for always serving fresh, personalized data — exactly what you want for dashboards, authed pages, and anything tied to the current user.
Triggering SSR Implicitly
Any of these in a route force dynamic rendering in Next 15:
import { cookies, headers } from 'next/headers'
export default async function Page() {
const c = await cookies()
const token = c.get('token')?.value
// Reading cookies() forces SSR
} The same goes for headers() and dynamic searchParams props. Once Next sees one of
these calls, it cannot prerender — the result depends on the request.
Opting a Fetch Out of the Cache
const data = await fetch('https://api.example.com/me', {
cache: 'no-store',
}).then((r) => r.json()) no-store means “never cache this response”. The page that contains it becomes dynamic
because at least one of its inputs is uncacheable.
The Trade-off
SSR pays full server cost on every request — DB queries, API calls, render time. Use it when freshness matters more than the millisecond cost. For pages that mostly stay the same, prefer SSG or ISR.
Forcing Dynamic Rendering →