Deep dive
These terms describe *when* HTML is generated and how freshness is handled.
- **SSR (Server-Side Rendering)**: render on each request. Best for highly dynamic or personalized pages, but can be slower and more expensive at scale.
- **SSG (Static Site Generation)**: render at build time. Extremely fast at runtime (CDN), but content is as fresh as your last build.
- **ISR (Incremental Static Regeneration)**: serve a cached/static version and regenerate in the background after a revalidate interval.
App Router mapping
In the App Router, this is mostly controlled by caching/revalidation:
- static + cached data → SSG-like,
- `revalidate` → ISR-like,
- `no-store` / dynamic route segment → SSR-like.
Example
// Revalidate this route every 60s (ISR-like)
export const revalidate = 60
// Per-request (SSR-like)
await fetch(url, { cache: 'no-store' })
Practical guidance
- Use SSG/ISR for content that can be slightly stale (marketing/docs/content pages).
- Use SSR for auth-dependent dashboards and per-user pages.
Common pitfalls
- Accidentally forcing SSR by reading `cookies()`/`headers()` where you expected static output.
- Overusing SSR and losing CDN caching benefits.
- Setting long revalidate windows for data that must be fresh.