NextJS. Use notFound in getStaticProps and some dynamic data? Don’t forget to revalidate!

igaponov

Igor

Posted on July 4, 2022

NextJS. Use notFound in getStaticProps and some dynamic data? Don’t forget to revalidate!

If you have static pages in NextJS and some dynamic data decides whether to return “notFound” or not, always use “revalidate” in return statement.


I will show you what I mean, because such case is not excluded at all.

We are going to use NextJs и Express.

Creating NextJS project

Let’s create NextJs application by running:

yarn create next-app --typescript
Enter fullscreen mode Exit fullscreen mode

After the installation is complete, run yarn dev to start the development server on http://localhost:3000.

If you open the page, you will see something similar to the following:

NextJS welcome page

Inside pages create file [url].tsx with the contents:

export const getStaticPaths = async () => {
    return {
        paths: [
            {
                params: {
                    url: 'test',
                }
            },
        ],
        fallback: 'blocking',
    }
}

export const getStaticProps = async () => {

    // Request to api
    const response = await fetch('http://localhost:3001')
    const body = await response.json()

    // If page not exists return "Not found"
    if (!body.status) {
        return {
            // This can be a problem without revalidate
            notFound: true
        }
    }

    return {
        props: {
            response: body,
        },
        revalidate: 10,
    }
}

export default function Url() {
    return (
        <p>Hello world</p>
    )
}
Enter fullscreen mode Exit fullscreen mode

This is the crucial moment:

// If page not exists return "Not found"
if (!body.status) {
    return {
        // This can be a problem without revalidate
        notFound: true,
    }
}
Enter fullscreen mode Exit fullscreen mode

If on the build stage your page returns notFound, it will always be not found, even if body.status will be true in the future

Let’s check it and run test server using Express.


Create project for Express server

Create new project and install Express.

In command line run:

yarn add -D express @types/express nodemon ts-node typescript
Enter fullscreen mode Exit fullscreen mode

Add to package.json:

"main": "index.ts",
"scripts": {
  "start": "nodemon index.ts"
},
Enter fullscreen mode Exit fullscreen mode

In order to get the following:

{
  "main": "index.ts",
  "scripts": {
    "start": "nodemon index.ts"
  },
  "devDependencies": {
    "@types/express": "^4.17.13",
    "express": "^4.18.1",
    "nodemon": "^2.0.18",
    "ts-node": "^10.8.1",
    "typescript": "^4.7.4"
  }
}
Enter fullscreen mode Exit fullscreen mode

In the root of that project create file index.ts:

import express from 'express'

const app = express()
const port = 3001
app.get('/', (req, res) => {
    res.send({ status: false })
})

app.listen(port, () => {
    console.log(`⚡️[server]: listening on port ${port}`)
})
Enter fullscreen mode Exit fullscreen mode

Pay attention, that we are returning false status for the page:

res.send({ status: false })
Enter fullscreen mode Exit fullscreen mode

Now run the server:

yarn start
Enter fullscreen mode Exit fullscreen mode

Reproduce the error and fix it

Let’s get back to NextJS project, run in the terminal:

yarn build
Enter fullscreen mode Exit fullscreen mode

Then run NextJS server:

yarn start
Enter fullscreen mode Exit fullscreen mode

Open the page http://localhost:3000/test and you will get 404 page. Try to refresh the page and you still get 404 error. This is because, when page was built, it got the status: false from our server in this line:

const response = await fetch('http://localhost:3001')
Enter fullscreen mode Exit fullscreen mode

Consider, that now server returns true.

Go to the Server project and change the status:

res.send({ status: true })
Enter fullscreen mode Exit fullscreen mode

Make sure that server was rebooted.

For NextJS project we are not doing rebuild, just checking the page http://localhost:3000/test. Nothing changes. Wait a bit, make one more refresh. Still got 404.

To fix such behaviour add revalidate: 5 in file [url].tsx:

if (!body.status) {
    return {
        notFound: true,
        // We use 5 only for demonstration purpose
        revalidate: 5
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, you will have a page rebuild, if it was not available and then the status was changed to available. It is called incremental static regeneration.

I’ll describe how to check that everything was fixed.

In Server project return back:

res.send({ status: false })
Enter fullscreen mode Exit fullscreen mode

Make sure that server was rebooted.

In NextJS project run commands yarn build and yarn start.

Go to the page http://localhost:3000/test and make sure that it returns 404 page.

In Server project set status true:

res.send({ status: true })
Enter fullscreen mode Exit fullscreen mode

Make sure that server was rebooted. Return back to the page [http://localhost:3000/test](http://localhost:3000/test, refresh, it will be 404 page. Wait for 5 seconds, NextJs triggers a regeneration. Now, if you reload the page, it should be available.

This is it! Thank you for reading.

💖 💪 🙅 🚩
igaponov
Igor

Posted on July 4, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related