DEV Community

Mohammad Faisal
Mohammad Faisal

Posted on • Originally published at betterprogramming.pub

How To Choose Data Fetching Strategies In NextJS

To read more articles like this, visit my blog

NextJS is a framework we React developers love and admire. It’s high in demand and very, very powerful.

But when you start to learn this, you will see that ReactJS and NextJS mainly differ in the capability of pre-rendering, which can be a little tricky to grasp at first.

There are multiple strategies for us to choose and it gets confusing at first to apply the correct solution in the correct place. We will take a real-life application and understand which strategy works best for which scenarios.

Let's get started.

The Functions

I hope you already have a basic understanding of NextJS. If not, I suggest you read this article first.

The special functions that are used for pre-rendering in NextJS(but not present in ReactJS) are:

  • getStaticProps

  • getStaticPaths

  • getServerSideProps

We will see in which scenarios you can apply these functions and learn the best practices.

We Are Talking About an Ecommerce Website

The biggest disadvantage of using React is that it’s hard to make it SEO-friendly. But for an e-commerce website, that’s one of the major things you need.

So let’s assume we are building an e-commerce website with multiple pages. Let’s start designing this.

Products Page (Predictable)

The home page of our ecommerce website is the products page, where you can see a list of products. You already know which products to show. There can be multiple strategies like:

  • Getting popular products

  • Getting featured products

  • Getting discounted products

Whatever the case, the main thing is you already know which API you need to call and that API is not changing or depending on some other info. In these scenarios only getStaticProps is enough.

export async function getStaticProps(context: GetStaticPropsContext) {
    const products = await getProducts ();

    return {
        props: {
            products
        }
    };
}
Enter fullscreen mode Exit fullscreen mode

Now our products page will be pre-generated ahead of time and won’t change.

Products Page (Dynamic)

But if you are building a website where the top products are changing frequently based on some algorithm then you don’t want to show the same page all the time.

In this case, you need to make sure that the generated pages are being updated at a regular interval.

Then, you have to use the revalidate property. We can define a number in seconds to indicate the refresh interval.

export async function getStaticProps(context: GetStaticPropsContext) {
    const products = await getProducts();

    return {
        props: {
            products,
        },
        revalidate: 10,
    };
}
Enter fullscreen mode Exit fullscreen mode

We have given a value of 10. It means we are still pre-generating our products page, but it will be updated every 10 seconds. This is called incremental static re-generation.

Product Details Page (Predictable But Dynamic)

Now, when our users click on a certain product, we have to show a details page of the product. We are calling an API like /product-details/?productId=123.

The interesting part is we don’t know which productID are we looking for. So our server needs to know all of the valid productId’s ahead of time.

This is where getStaticPaths comes in. It tells the server all the available routes that we need to pre-generate.

export async function getStaticPaths() {

    //get products
    const products = getproducts();

    //ger product id list
    const idList = products.map(product => product.id)

    //convert them into params
    const params = idList.map(id => ({params: {productId: id}}))

    return {
        fallback: false, 
        paths: params,
    };
}

export async function getStaticProps(context: GetStaticPropsContext) {
    // we have the productId inside the params of context
    const {params} = context
    const productId = params.productId

    //use that productId to get details
    const productDetails = await getProductDetails(productId);

    return {
        props: { productDetails, }
    };
}
Enter fullscreen mode Exit fullscreen mode

Now, only the pages with a valid productId will be pre-generated.

Accounts Page (Dynamic and Secure)

Now there are some pages where we want to validate some things. For example on the profile page of the user. We don’t want to pre-generate all the user's profiles and show them when needed.

Or maybe we want to make sure that the user has the right permission to view the page. In these scenarios, we use getServerSideProps.

Remember one thing: If you use getServerSideProps, it will not pre-generate any page. Instead, it will run the code inside the getServerSideProps every time the page is requested.

So this is more secure but inefficient. You will want to use it as little as possible.

export async function getServerSideProps(context: GetServerSidePropsContext) {
    const request = context.req;

    //check if the user is valid (maybe check headers or whatever)
    const isUserValid = validateUser(request);

    //user is not valid
    if(!isUserValid)  return { notFound: true }

    //get the details because the user is valid
    const userDetails = getUserDetails(request)

    return { 
      props: {
        userDetails
      }
    }
}
Enter fullscreen mode Exit fullscreen mode

There is one other scenario where you can’t even use getServerSideProps.

Live Visitor Count (Very Highly Dynamic)

Now, if you are designing a page where you need to show some data that changes every time, for example, the live visitor count of your website, you can’t use any of the above four approaches. Instead, you have to rely on the good old client-side data fetching.

For this purpose, you can use any library like axios, fetch, useSWR, etc. That’s your choice.

Conclusion

That’s it. Now you should have a clear understanding of the possible scenarios of a modern application and how you can leverage the power of pre-rendering in NextJS for improved performance and SEO support in your application.

Let me know if you have any comments.

Have a great day!

Have something to say? Get in touch with me via LinkedIn or Personal Website

Top comments (0)