Master Static Site Generation (SSG) and Incremental Static Regeneration (ISR) to shift rendering to build time and deliver lightning-fast, scalable React apps.
Previously in this course, we explored Streaming Server-Side Rendering to improve Time to First Byte (TTFB) by flushing HTML incrementally. While streaming SSR excels at dynamic, user-specific data, it still incurs a server-side cost for every request. This lesson introduces Static Site Generation (SSG), a pattern that trades runtime server cycles for near-instant delivery by moving rendering to build time.
At its core, SSG means generating the HTML for a page at build time rather than at request time. When a user requests a static page, the server (or CDN) simply serves a pre-rendered file.
This eliminates the "cold start" of server-side logic, database queries, and component reconciliation for every request. The result is a performance profile that is essentially limited only by the speed of your CDN.
| Feature | Static Site Generation (SSG) | Server-Side Rendering (SSR) |
|---|---|---|
| Rendering Time | Build Time | Request Time |
| Data Freshness | Stale until next build | Real-time |
| Server Load | Extremely Low (CDN heavy) | High (Compute heavy) |
| Use Case | Blogs, Marketing, Docs | Dashboards, User feeds |
In a modern React framework (like Next.js), you implement SSG by defining how a page fetches data during the build process. Instead of fetching data inside useEffect or relying on runtime SSR functions, you use build-time data hooks.
Imagine we are building a product catalog for our project. We want the product pages to be as fast as possible. We use getStaticProps (or equivalent build-time functions) to fetch the data once when the site is deployed.
JAVASCRIPT// pages/products/[id].js // This function runs at build time export async function getStaticProps({ params }) { const product = await fetchProductFromAPI(params.id); return { props: { product }, // Incremental Static Regeneration: Re-validate every 60 seconds revalidate: 60, }; } // This function tells the build system which paths to pre-render export async function getStaticPaths() { const products = await getAllProductIds(); const paths = products.map((id) => ({ params: { id } })); return { paths, fallback: CE9178">'blocking' }; } export default function ProductPage({ product }) { return <div>{product.name} - {product.price}</div>; }
The biggest drawback of pure SSG is that updating content requires a full site rebuild. If you have 10,000 product pages, a rebuild for a price change is inefficient.
ISR solves this by allowing you to update static pages in the background after the site is deployed. By adding a revalidate property to your build-time logic, you tell the server: "If a request comes in after X seconds, serve the cached version, but trigger a background regeneration of this page."
This gives you the best of both worlds: the performance of static files and the flexibility of dynamic updates.
useEffect into a build-time data function.revalidate window (e.g., 3600 seconds for one hour) to ensure your content stays fresh without needing a redeploy for minor updates.npm run build) and inspect the output. You should see static HTML files generated for these routes.revalidate to 1 second for highly volatile data. Use it for content that changes periodically. If you need true real-time updates, use client-side fetching with React Query instead.getStaticPaths: If you have millions of pages, building them all at once will crash your build pipeline. Use fallback: 'blocking' to generate pages on-demand the first time they are requested, rather than pre-building every single possible route.SSG turns your React application into a set of highly optimized static files. By leveraging getStaticPaths to define your routes and revalidate to manage content freshness through ISR, you can scale your application to handle massive traffic with minimal compute cost. Remember to balance the need for performance against the need for data freshness when deciding between SSG and SSR.
Up next: We will explore Internationalization (i18n) Architecture, focusing on how to manage localized content without destroying your performance gains.
Learn to architect performant i18n in React. Implement lazy-loaded translations, optimize re-renders during locale switches, and manage locale state efficiently.
Read moreStop managing manual boolean loading flags. Learn to implement Suspense boundaries to orchestrate data fetching and create seamless, declarative loading states.
Static Site Generation (SSG) Patterns
Managing Third-Party Integrations
Advanced Form Handling
Using Portals for UI Overlays
Implementing Virtualized Lists
Building Design System Primitives
Managing Large-Scale Data Fetching
Micro-Frontends with React
Security Best Practices in React
Advanced Ref Usage
Memoization Pitfalls
Mastering React Patterns for Scalability
Advanced TypeScript with React