Explain static generation of React applications and its benefits
TL;DR
Static generation (SSG) pre-renders pages to HTML at build time, instead of rendering them per request. The output is plain files that can be served from a CDN, which makes loads fast and SEO straightforward. Frameworks like Next.js, Remix, Astro, and Gatsby support it; in Next.js's App Router, fetches are statically generated by default and generateStaticParams enumerates dynamic routes at build. Incremental Static Regeneration (ISR) lets you re-build individual pages in the background after a TTL, so static does not have to mean stale. SSG is best for content that does not vary per user and does not need to be perfectly fresh.
Static generation of React applications and its benefits
What is static generation?
Static generation is a method of pre-rendering where the HTML of a page is generated at build time. This means that the HTML is created once, during the build process, and then reused for each request. In the context of React applications, this is often achieved using frameworks like Next.js.
How does static generation work?
- Build time rendering: During the build process, the framework generates the HTML for each page based on the React components and data.
- Static files: The generated HTML, CSS, and JavaScript files are then stored as static files.
- Serving the files: These static files can be served directly from a CDN or a web server, without the need for server-side rendering on each request.
Benefits of static generation
Improved performance
- Faster load times: Since the HTML is pre-generated, it can be served immediately without waiting for server-side rendering.
- Reduced server load: Static files can be served from a CDN, reducing the load on the origin server.
Better SEO
- Search engine indexing: Pre-rendered HTML is trivially indexable — crawlers do not need to execute JavaScript to see the content.
- Consistent content: Every request returns the same HTML, so what crawlers see matches what users see.
Scalability
- CDN distribution: Static files can be replicated across CDN edges, so traffic spikes are absorbed at the edge instead of hammering an origin.
- Efficient caching: Static files have stable URLs and content hashes, which makes long-lived browser and CDN caching straightforward.
Example with Next.js (App Router)
In the Next.js App Router, server components are statically rendered by default unless you opt into dynamic behavior. For dynamic routes, generateStaticParams enumerates the params to pre-render at build time.
// app/posts/[slug]/page.jsxasync function getPost(slug) {const res = await fetch(`https://api.example.com/posts/${slug}`);return res.json();}export async function generateStaticParams() {const posts = await fetch('https://api.example.com/posts').then((r) =>r.json(),);return posts.map((post) => ({ slug: post.slug }));}export default async function PostPage({ params }) {const post = await getPost(params.slug);return (<article><h1>{post.title}</h1><p>{post.body}</p></article>);}
At build time Next.js calls generateStaticParams to learn the list of slugs, renders each PostPage to HTML, and ships the result as static files.
Incremental Static Regeneration (ISR)
ISR lets you keep the speed of static while still picking up content updates. You declare a revalidation window (in seconds) and the framework serves the cached HTML; after the window expires, the next request triggers a background re-render and subsequent requests get the fresh version.
// app/posts/[slug]/page.jsxexport const revalidate = 60; // secondsexport default async function PostPage({ params }) {const post = await getPost(params.slug);return <article>{post.title}</article>;}
You can also revalidate on demand (e.g. from a webhook) using revalidatePath or revalidateTag, which is useful for CMS-driven content.
When SSG is not a good fit
- Per-user content: Anything personalized (auth-gated dashboards, "hello {user}", carts) cannot be pre-rendered for every visitor — use SSR or client-side fetching for the personalized parts.
- Highly dynamic data: Live prices, stock levels, scoreboards, etc. need fresher data than even ISR comfortably provides.
- Huge or unbounded route spaces: If
generateStaticParamswould emit millions of pages, build time and storage become a problem. Mitigations include partial pre-rendering (build the popular pages, defer the rest to on-demand SSR/ISR) or moving to SSR. - Stale-data tradeoffs: Plain SSG serves whatever was true at build time until the next deploy. ISR shortens that window but always serves the previous version on the request that triggers revalidation, so users may see slightly stale content.