Next.js - Static Site Generation



Static Site Generation is a optimization technique used in Next.js, by which HTML pages are rendered quickly on user interface. In this chapter we will learn what is static site generation, benefits of static site generation, and how to implement static site generation while fetching data from external source.

What is Static Rendering?

Static Rendering (or Static Site Generation) is a server rendering strategy where we generate HTML pages at the time of building application. That means in production, the HTML page is generated when we run 'next build'. This HTML will then be reused on each request.

  • In Static Rendering, a HTML page is built once, which then cached by CDN and severed to the client almost instantly.
  • This type of rendering improves performance and user experience of the application.
  • By default all the Next.js components that does not involve fetching data from external source follows static rendering strategy.
  • Static rendering is commonly used in blog pages, documentation pages, and marketing pages.

Static Generation Without Fetching Data

As mentioned above, all the components that doesn't involve fetching data from external resource will be generated statically. See the example below.

Example

This is a static 'About' page, which will be same for all the users. Hence this page will be generates once at build time and then stored as cache.

export default function About() {
    return (
      <div>
        <h1>About Us</h1>
        <h2>Welcome to the Tutorialspoint About page!</h2>
        <h4>This page is same for all users</h4>
      </div>
    );
}

Output

The output of above code will be a simple HTML page for About section. This page will same for all users.

Static site

Static Generation by Fetching External Data

If you want to create static page that fetch data during build time, you can use 'getStaticProps()' function. This function will fetch data once at build time, and then create a complete HTML file based on it. This HTML file will be served to all users. See the example below.

Example

In this code below we will fetch API data using 'getStaticProps()' function at build time, and then pass it to React component as prop.

// app/page.tsx

import React from 'react';

// Receive posts prop from getStaticProps function
export default function Blog({ posts }) {
  return (
    <div>
      <h1>Blog Posts</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  );
}

// Export getStaticProps function to fetch data during build time
export async function getStaticProps() {
    // Simulate fetching data from an API
    const response = await fetch('https://link/to/api');
    const posts = await response.json();
  
    return {
      props: {
        posts, // This will be passed to Blog component as props
      },
    };
}

Output

In this output, we are displaying data from an API in static page.

SSR external data

Static Generation in Dynamic Routes

Static generation will also work on pages with dynamic routes. Dynamic Routes indicate that the route (ie, the URL) of page will depend on data from external source. For example, you can create a file called pages/product/[id]/page.tsx to show products based on their IDs. This will allow you to show a product with id: 1 when you access localhost/product/1

Example

To handle dynamic routing url, Next.js lets you export an async function called 'getStaticPaths' from a dynamic page (pages/product/[id]/page.tsx. in this case). This function gets called at build time and lets you specify which paths you want to pre-render.

// pages/product/[id]/page.tsx file

// This function gets called at build time
export async function getStaticPaths() {
    // Call an external API endpoint to get product ids
    const res = await fetch('https://link/to/api');
    const products = await res.json();
    
    // Get the paths we want to pre-render based on products
    const paths = products.map((product) => ({
        params: { id: product.id.toString() }, // Ensure id is a string
    }));
    
    // We'll pre-render only these paths at build time.
    // { fallback: false } means other routes should 404.
    return { paths, fallback: false };
}

// This also gets called at build time
export async function getStaticProps({ params }) {
    // params contains the product `id`.
    // If the route is like /product/1, then params.id is 1
    const res = await fetch(`https://.../product/${params.id}`);
    const product = await res.json();
    
    // Pass product data to the page via props
    return { props: { product } };
}

// Page component to display the product details
export default function ProductPage({ product }) {
  return (
    <div>
      <h1>Product {product.id}</h1>
      <p>This is the product page for item {product.id}</p>
      <p>Title: {product.title}</p>
    </div>
  );
}

Output

This is output for dynamic routing. The page changes based on product ID fetched from server.

ssr-dynamic-routing

When to Use Static Site Generation?

Static Site Generation is ideal for pages that:

  • Have content that rarely changes, such as blogs or documentation.
  • Need to load quickly for better user experience and SEO.
  • Can tolerate data being slightly outdated, as updates require rebuilding the site.
Advertisements