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
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:
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>
)
}
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,
}
}
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
Add to package.json
:
"main": "index.ts",
"scripts": {
"start": "nodemon index.ts"
},
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"
}
}
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}`)
})
Pay attention, that we are returning false
status for the page:
res.send({ status: false })
Now run the server:
yarn start
Reproduce the error and fix it
Let’s get back to NextJS project, run in the terminal:
yarn build
Then run NextJS server:
yarn start
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')
Consider, that now server returns true
.
Go to the Server project and change the status
:
res.send({ status: true })
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
}
}
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 })
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 })
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.
Top comments (0)