Data Fetching in NextJS - Server Side Rendering (SSR)

This tutorial explains fetching data in Nextjs using the Server-side rendering technique. At the end of this article, you should be able to understand how to fetch your data on the server-side in Nextjs using a Server-side Rendering (SSR) function called getServerSideProps, and the benefits it offers.

Requirements for this Tutorial

  • An understanding of HTML, CSS, Javascript fundamentals
  • An understanding of React fundamentals
  • A beginner's knowledge in Nextjs to get you started

Overview

When using React without any framework, what happens is that the entire app gets delivered to the user any time they come to the website. This is good, but as your app becomes bigger, visiting the website gets slower as the entire bundle would need to be loaded (this is because javaScript code initially can take a long time to load on the browser). This can sometimes get annoying as you now have to wait for the entire website to load.

This is where Nextjs comes in, introducing a data fetching technique called Server-side Rendering (SSR). This way, when a user visits a website, each individual page is going to get pre-built on a fast server.

Data Fetching in NextJS

Data fetching in NextJs can be achieved in different ways, depending on your use case. These are:

  1. Server-side Rendering (SSR)
  2. Static-site Generation (SSG)
  3. Incremental Static Regeneration (ISR) - A technique that allows for updating or creating content at runtime in NextJs

In this tutorial, we would focus on the SSR technique. The SSR technique is used to take care of some of the shortcomings of using the Static generation.

Let's see some of the problems with fetching data using the Static Generation technique

  • Inability to fetch data at request time: With not being able to fetch data per request, we tend to run into the problem of stale data. Let’s take a news blog for example. We would expect new articles to be published regularly, hence, making the contents of the blog/website dynamic. Using static generation fetches the data(in this case news) only at build time, but is then cached for subsequent requests, which is not suitable for our type of website.
  • Being unable to fetch data that is user-specific and rerendered on the page. You could do it on the client-side using the useEffect hook, but this would have to be a compromise for SEO.

Server-side Rendering (SSR)

SSR is required when you need to fetch data per request. With Nextjs, you can pre-render the pages of your website at request time instead of at build time.

To use the SSR technique, you need to export an asynchronous function called getServerSideProps() which would be called by the server on every request. Inside the function, you can then fetch external data and send it to the page as props.

Using getServerSideProps

This is an asynchronous function that should be used only if you need to render a page whose data must be fetched at the request time.

The getServerSideProps function takes the format below:

export async function getServerSideProps() {
    // Fetch data from external API
    const res = await fetch(`https://{endpoint-url}/data`);
    const data = await res.json();

    return {
        props: {
            data: data,
        }, // will be passed to the page component as props
    };
}

To get the function to your component, return the data with props as a key-value object using props.

The data generated would then be sent to your page to be rendered as so:

export default const Home = ({ data }) => {
  return (
    // Rendered data...
  )
}

Note that this form of pre-rendering is slower when compared to using static-site generation as the server must compute the result on every request.

To work with this, you can make parts of the page pre-rendered using Static Generation and then, fetch the data on the client-side to display it when ready.

Using getServerSideProps for dynamic parameters

To implement this component, we need to filter by our parameter and fetch the filtered parameter using getServerSideProps to make our API call.

For a sample news website that contains different categories, if you want to filter and get all results for a category (e.g entertainment), let's make an API call to that route using our getServerSideProps so that that page is rendered dynamically i.e. /news/entertainment

  • Create a route in your pages directory by creating a new folder (e.g news)
  • Create a new file with a slug within square brackets in the created folder. i.e mkdir news >> touch [category.js]. This would be our parameter. ssr1.png

This takes the format of:

export async function getServerSideProps(context) {
    const { params } = context;
    const { parameter } = params; 
//in the case of our news website, our parameter would be the category

    // Fetch data from external API
    const res = await fetch(
        `https://{endpoint-url}/data?parameter=${parameter}`
     );
    const data = await res.json();

    return {
        props: {
            data: data,
            parameter,
        }, // will be passed to the page component as props
    };
}

The data generated would then be sent as props to your page to be rendered as so:

export default const Category = ({ data, category }) => {
  return (
    // Rendered data...
  )
}

Some advantages of the getServerSideProps for Server-side Rendering (SSR) are:

  • It allows pages on your website to load faster
  • It promotes a better user experience
  • Better SEO performance

Thank you so much for taking your time to read.

Please let me know if something isn't clear enough in the comments below. Also, let me know if you want me to cover something else.

Here are some of the resources that helped me: