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 }))
}