Next.js Data Fetching: Everything to Know About CSR, SSR, SSG, and ISR

Learn the data fetching methods: SSG, SSR, ISR, and CSR.

Picture of Nsikak Imoh, author of Macsika Blog
Next.js Data Fetching: Everything to Know About CSR, SSR, SSG, and ISR written on an abstract silhouette background
Next.js Data Fetching: Everything to Know About CSR, SSR, SSG, and ISR written on an abstract silhouette background

Table of Content

One thing I found puzzling when I started taking tutorials on Next.js, is the Data fetching procedure.

I kid you not. I could not differentiate what they meant.

Not only that, but I found myself combining through tutorials upon tutorials, trying to satisfy a part of my brain that just didn't quite get it.

And when I did, I promise to write it down in the simplest way, so my future self can always return to it.

It's not just me. It is easy for any dev to get overwhelmed about CSR, SSR, SSG, and ISR and their differences.

This is worse if you come from a Create React App where data fetching from an API is done using the useEffect hook.

Even though it started as a Server-Side Rendering Framework using React.js Library, Next.js has morphed into a giant, which even has another framework built on it called Blitz.js.

Suggested Post: What is React Router, Why use it, and How?

What is Data Fetching in Next.js?

Data fetching is the process of getting data through an API endpoint to either manipulate an input or display the returned data using the data fetching methods: SSG, SSR, ISR, and CSR.

This is different from passing data from one Next.js component, a parent component, to another component, a child component.

How to Perform Data Fetching In Next.js?

There are four ways to carry out Data Fetching in Next.js abbreviated as SSG, SSR, ISR, and CSR.

  1. Static Site Generation (SSG)

    Static Site Generation (SSG) is a Next.js data fetching method that executes a special Next.js built-in function to fetch data once when that page builds.

  2. Server-Side Rendering (SSR)

    Server-Side Rendering (SSR) is a Next.js data fetching method that executes a special Next.js built-in function to fetch data from an API endpoint on every page request.

    The code is rendered on the server-side before the page loads and gets served to the client.

  3. Incremental Static Regeneration (ISR)

    Incremental Static Regeneration (ISR) is a new, and I must say fantastic, addition to Next.js data fetching strategies.

    It combines the functionality of SSG, and SSR such that it initially serves a page statically, then at a certain time and after a certain condition it will rebuild the page, and fetch the data from the API again.

    To make this even better, Next.js released a new way of using the ISR called On-Demand Incremental Static Regeneration that lets you revalidate when the data changes when the page is requested without the need for a revalidate period.

  4. CSR - Client-Side Rendering

    Client-Side Rendering (CSR) is the usual kind of data fetching that is common in React using useEffect.

    It will fetch the data from the API endpoint on every single page request at the client side.

    This means that the function runs after the page is rendered.

    In Next.js, a React hook library for data fetching has been developed called SWR, which aids data fetching on the client-side.

Suggested Post: How to Configure Routes in ReactJS with React Router

Now let us look in-depth at each data fetching method in Next.js.

Which Function is used to Fetch Data in Next.js?

I mentioned earlier that Next.js has special built-in functions for data fetching that runs based on the specified data fetching method.

Here is the list of data fetching functions in Next.js:

  • getStaticProps for Static Site Generation (SSG) and Incremental Static Site Generation (ISR) using the revalidate prop.
  • getStaticPaths for Static Site Generation (SSG) and Incremental Static Site Generation (ISR).
  • getServerSideProps for Server-Side Rendering (SSR).
  • useEffect for regular Client-Side Rendering (CSR).
  • useSWR for Client-Side Rendering (CSR) using Next.js SWR React hook data fetching library.

What is Static Site Generation (SSG) in Next.js?

Static Site Generation (SSG) in Next.js can be easily defined by the three points below.

  1. The getStaticProps function is what indicates that a page is using Static Site Generation for data fetching in Next.js.

  2. The getStaticPaths function is used if a page has Next.js Dynamic Routes and uses getStaticProps.

    It needs to define a list of paths to be statically generated.

  3. A page that uses the Static Site Generation (SSG) data fetching method in Next.js, fetches the data when you run npm run build or yarn build.

    It will access the API endpoint during the build time of the application only.

  4. The data will be stale as no further fetch occurs after the page is built.

How to Use Static Site Generation (SSG) in Next.js

To implement Static Site Generation (SSG) data fetching method, you have to export a function called getStaticProps from a page in the Next.js pages directory.

Next.js will pre-render this page at build time using the data returned by getStaticProps.

Code Example for Data Fetching in Next.js Using Static Site Generation (SSG):


import { GetStaticProps, InferGetStaticPropsType } from 'next';
import type { NextPage } from 'next';
import axios from "axios"


const StaticGeneration: NextPage = (props: InferGetStaticPropsType<typeof getStaticProps>) => {
    return (
        <main>
            <TimeSection dateTime={props.dateTime} />
        </main>
    );
}
export default StaticGeneration;

export const getStaticProps: GetStaticProps = async () => {
    const res = await axios.get('https://worldtimeapi.org/api/ip');

    return {
        props: { dateTime: res.data.datetime },
    };
};    
Highlighted code sample.

What is Server-Side Rendering (SSR) in Next.js?

We can define Server-Side Rendering (SSR) in Next.js by the three points below.

  1. The getServerSideProps function indicates that a page uses Static Site Generation for data fetching in Next.js.

  2. A page that uses the Server-Side Rendering (SSR) data fetching method in Next.js,1. fetches the data before rendering it.

    As a result, there will be a slight delay when we access the API endpoint before it shows the page.

  3. The data will not be stale because we fetch it on every page request.

How to Use Server-Side Rendering (SSR) in Next.js

To implement the Server-Side Rendering (SSR) data fetching method, you will export a function called getServerSideProps from a page in the Next.js pages directory.

Next.js will pre-render this page every time we request it using the props returned by getServerSideProps.

Code Example for Data Fetching in Next.js Using Server-Side Rendering (SSR):


import { GetServerSideProps, InferGetServerSidePropsType } from 'next';
import type { NextPage } from 'next';
import axios from "axios"


const ServerSideGeneration: NextPage = (props: InferGetServerSidePropsType<typeof getServerSideProps>) => {
    return (
        <main>
            <TimeSection dateTime={props.dateTime} />
        </main>
    );
}
export default ServerSideGeneration;
    
export const getServerSideProps: GetServerSideProps = async () => {
    const res = await axios.get('https://worldtimeapi.org/api/ip');

    return {
        props: { dateTime: res.data.datetime },
    };
};    
Highlighted code sample.

What is Incremental Static Regeneration (ISR) in Next.js?

With ISR, you can retain the benefits of static while scaling to millions of pages.

Incremental Static Regeneration (ISR) in Next.js can be easily defined by the three points below.

  1. When the page is reloaded within the time set, changes will not occur.

    This event happens because the page is in a cooldown state, as we set on the revalidate key.

  2. After the revalidate period elapses, the first visit will trigger trigger ** a page rebuild**.

    A page rebuild means only this page will be rebuilt, not the entire application.

    The fetch API will run in the background, but there will be no changes.

    However, a second hard reload will serve that rebuilt page from the previous reload.

    It is imperative to distinguish a hard-reload from a simple page visit in Next.js

Difference Between a Hard Reload and Visiting Pages in Next.js

Simply revisiting pages means navigating using next/link. For example, visiting a different page and revisiting the page.

A hard-reload is involves reloading the page at a URL level by revisiting the web page itself.

When using Next.js ISR, the first reload does not have to be a full reload.

We can visit the home page, then back revisit the page, and it will trigger the rebuild as long as we are not in the cooldown state.

However, it is imperative for the second reload to be a hard-reload.

Visiting a different page and revisiting the page will not serve the rebuilt page.

What Happens After the Revalidate Time Expires in Next.js ISR?

When the revalidate time expires, if no one visits the page, that page will not rebuild, even if it stays years, unless there's a hard-rebuild of the entire site.

Other than a hard-rebuild of the entire site, the first visit to the page when the revalidate time expires will trigger a rebuild.

But the user behind the first visit will not see the changes. The next hard reload will display the page with the changes.

It is what mentioning that to you can completely avoid using the revalidate method for the incremental static regeneration by using Next.js on-demand incremental static regeneration.

Read more: What is Next.js On-demand Incremental Static Regeneration and How to Use it?

How to Use Incremental Static Regeneration (ISR) in Next.js?

Incremental Static Regeneration (ISR) uses both the getStaticProps with a revalidate prop and getStaticPaths function to indicate that a page uses Incremental Static Regeneration (ISR) for data fetching in Next.js.

To use ISR, add the revalidate prop to getStaticProps.

Code Example for Data Fetching in Next.js using Incremental Static Regeneration (ISR):


import { GetStaticProps, InferGetStaticPropsType } from 'next';
import type { NextPage } from 'next';
import axios from "axios"


const IncrementalStaticGeneration: NextPage = (props: InferGetStaticPropsType<typeof getStaticProps>) => {
    return (
        <main>
            <TimeSection dateTime={props.dateTime} />
        </main>
    );
}
export default IncrementalStaticGeneration;

export const getStaticProps: GetStaticProps = async () => {
    const res = await axios.get('https://worldtimeapi.org/api/ip');

    return {
        props: { dateTime: res.data.datetime },
        revalidate: 20,
    };
};    
    
Highlighted code sample.
export default function SSGPage({ dateTime };
Highlighted code sample.

What is Client-Side Rendering (CSR) in Next.js?

Static Site Generation (SSG) in Next.js can be easily defined by the three points below.

  1. There is a need for a loading indicator because the data fetching runs after the page is rendered.

    Given that the data is not immediately fetched when the page loads, we need to show a loading state to prevent the user from thinking the page is broken.

  2. The useEffect function is what indicates that a page is using Client-Side Rendering for data fetching in Next.js.

  3. The SWR library or other client-side data fetching libraries like React Query can also indicate the use of client-side fetching.

  4. A page that uses the Static Site Generation (SSG) data fetching method in Next.js is fetched on every page request.

    It will access the API endpoint after the page reloads.

How to use Client-Side Rendering (CSR) in Next.js with useEffect Hook

To implement the Client-Side data fetching method with useEffect, you have to import and call the useEffect Hook within the function of a page in the Next.js pages directory.

Code Example for Data Fetching in Next.js Using Client-Side Rendering (CSR) with useEffect Hook:



function Profile() {
    const [data, setData] = useState(null)
    const [isLoading, setLoading] = useState(false)

    useEffect(() => {
        axios
          .get('https://worldtimeapi.org/api/ip')
          .then((res) => {
            setDateTime(res.data.datetime);
            setLoading(false)
          })
          .catch((error) => console.error(error));
      }, []);

    if (isLoading) return <p>Loading...</p>
    if (!profileData) return <p>No profile data</p>

    return (
        <div>
            <h1>{data.name}</h1>
            <p>{data.bio}</p>
        </div>
    )
}
Highlighted code sample.

How to use Client-Side Rendering (CSR) in Next.js with SWR Library

To implement the Client-Side data fetching method with useSWR, you have to import and call the useSWR Hook within the function of a page in the Next.js pages directory.

Code Example for Data Fetching in Next.js Using Client-Side Rendering (CSR) with useSWR Hook:


import useSWR from 'swr'

const fetcher = (...args) => fetch(...args).then((res) => res.json())

function Profile() {
    const { data, error } = useSWR('https://worldtimeapi.org/api/ip', fetcher)

    if (error) return <div>Failed to load</div>
    if (!data) return <div>Loading...</div>

    return (
    <div>
        <h1>{data.name}</h1>
        <p>{data.bio}</p>
    </div>
    )
}    
Highlighted code sample.

Wrap Off

Data fetching is the process of getting data through an API endpoint to either manipulate an input or display the returned data using the data fetching methods: SSG, SSR, ISR, and CSR.

Next.js has special built-in functions for data fetching that runs based on the specified data fetching method.

Now that we have looked into the four main types of data fetching in Next.js, I hope you can easily differentiate and use them appropriately.

If you learned from this tutorial, please share.

Connect with me.

Need an engineer on your team to grease an idea, build a great product, grow a business or just sip tea and share a laugh?