Static Rendering (SSG)
Static rendering means this page's HTML is generated ONCE — at build time — and that exact same HTML is served to every visitor, with no server work per request. It's the fastest and cheapest way to serve a page.
1. force-static freezes this page
Run `npm run build && npm start` to see the real effect: this timestamp is baked in at build time and stays frozen no matter how many times you refresh or how many different visitors load it. (In `npm run dev`, Next.js re-runs the page each time to keep development fast, so you won't see it freeze until you build.)
// app/static-demo/page.tsx
export const dynamic = 'force-static'
export default async function StaticDemoPage() {
const generatedAt = new Date().toISOString()
return <p>Generated at build time: {generatedAt}</p>
}Live result
Generated at: 2026-07-30T09:51:25.088Z
2. Static vs SSR vs Server Components — which is which?
These three ideas overlap but answer different questions: WHERE does it render (server, always), WHEN (build time vs every request), and WHAT ships to the browser (HTML only vs HTML + interactive JS).
Server Component -> WHAT: no JS for this component ships to the browser
SSR (force-dynamic) -> WHEN: HTML is (re)built on every request
SSG (force-static) -> WHEN: HTML is built once and reused
A page can be a Server Component AND statically rendered AND still
render a Client Component (like our Counter) inside it for interactivity.3. Why static rendering
Use it for content that's the same for every visitor and doesn't change often: marketing pages, documentation, blog posts (like /blog/[slug] in this app, via generateStaticParams), pricing pages.
export function generateStaticParams() {
// pre-renders one static page per slug at build time
return getAllPosts().map((post) => ({ slug: post.slug }))
}