Static Site Generation (SSG) Deep Dive

Static Site Generation (SSG) Deep Dive

Deep Dive into Static Site Generation (SSG) and Incremental Static Regeneration (ISR)

What is Static Generation?

Static Generation (SSG) means that Next.js pre-renders pages at build time.
The output is a set of static HTML files that can be cached by the server or CDN, ensuring fast loading and SEO friendliness.

How It Works

  1. During npm run build, Next.js executes your page’s getStaticProps() function.
  2. The function fetches and prepares data on the server side, before deployment.
  3. Next.js builds static HTML + JSON for each page and stores them for direct serving.

getStaticProps() — Build-time Data Fetching

This function runs only on the server, and only at build time.
It never executes in the browser.

export async function getStaticProps() { return { props: { products: [{ id: "p1", title: "Product 1" }], }, }; }

The object returned by getStaticProps() must include:

  1. props: Data passed to the page component.
  2. (optional) revalidate: Enables Incremental Static Regeneration.

export async function getStaticProps() { console.log("regenerating..."); const filePath = path.join(process.cwd(), 'data', 'dummy-backend.json'); const jsonData = await fs.readFile(filePath); const data = JSON.parse(jsonData); return { props: { products: data.products, }, revalidate: 20, // Enable ISR }; }

Why revalidate Matters?

Without ISR, the page is generated once at build time — it never updates until you rebuild. ISR solves this by allowing automatic regeneration after deployment.

  1. revalidate: 20 → If more than 20 seconds have passed since the last generation, Next.js re-runs getStaticProps() on the server to rebuild the page in the background.
  2. The new version replaces the old static HTML once ready.
  3. This keeps performance high while ensuring data freshness.

Note: revalidate works only in production (npm run build && npm start), not in development mode (npm run dev).


getStaticPaths() — Pre-Rendering Dynamic Routes

For dynamic pages like /products/[pid].js, Next.js needs to know which paths to pre-render.

async function getData() { const filePath = path.join(process.cwd(), 'data', 'dummy-backend.json'); const jsonData = await fs.readFile(filePath); return JSON.parse(jsonData); } export async function getStaticPaths() { const data = await getData(); const ids = data.products.map(product => product.id); const pathsWithParams = ids.map(id => ({ params: { pid: id } })); return { paths: pathsWithParams, fallback: 'blocking', // or 'true' / 'false' }; }

Understanding fallback Options:

  1. false: Only pages returned by getStaticPaths() are pre-rendered. Any other path → 404.
  2. true: Unlisted paths initially show a loading state (CSR) while the server generates and caches the new page.
  3. 'blocking': Requests for new paths wait until the server generates the HTML, then return the fully rendered page (no loading state).
← PreviousNext →