I just installed a new Next.js app. It has the following page:
// /pages/articles/[slug].js
import React from 'react'
import { useRouter } from 'next/router'
import ErrorPage from 'next/error'
const Article = (props) => {
const router = useRouter()
if (router.isFallback) {
return <div>Loading..</div>
}
if (!props['data']) {
return <ErrorPage statusCode={404} />
}
return (
<div>
Article content
</div>
)
}
export default Article
export const getStaticProps = async(context) => {
const slug = context.params.slug
const res = ["a", "b", "c"].includes(slug)
? {
props: {
data: slug
}
}
: {
props: {},
notFound: true
}
return res
}
export const getStaticPaths = async () => {
return {
paths: [
{ params: { slug: "a" }},
{ params: { slug: "b" }},
{ params: { slug: "c" }}
],
fallback: true
}
}
When the browser navigates to a non-existing page (e.g. http://localhost:3000/articles/d) then it returns the default nextjs 404 page, as expected.
But the browser network tab shows status 200 for the main document (the 404 error page). The only things in the network tab with status 404 are d.json and 404.js.
I think that the main document should also have 404 status. The getStaticProps docs say about the return value:
- notFound - An optional boolean value to allow the page to return a 404 status and page
But in this case the page status is 200 and not 404. Is there something else necessary to do to return status 404?
Without fallback the status is 404.
I just installed a new Next.js app. It has the following page:
// /pages/articles/[slug].js
import React from 'react'
import { useRouter } from 'next/router'
import ErrorPage from 'next/error'
const Article = (props) => {
const router = useRouter()
if (router.isFallback) {
return <div>Loading..</div>
}
if (!props['data']) {
return <ErrorPage statusCode={404} />
}
return (
<div>
Article content
</div>
)
}
export default Article
export const getStaticProps = async(context) => {
const slug = context.params.slug
const res = ["a", "b", "c"].includes(slug)
? {
props: {
data: slug
}
}
: {
props: {},
notFound: true
}
return res
}
export const getStaticPaths = async () => {
return {
paths: [
{ params: { slug: "a" }},
{ params: { slug: "b" }},
{ params: { slug: "c" }}
],
fallback: true
}
}
When the browser navigates to a non-existing page (e.g. http://localhost:3000/articles/d) then it returns the default nextjs 404 page, as expected.
But the browser network tab shows status 200 for the main document (the 404 error page). The only things in the network tab with status 404 are d.json and 404.js.
I think that the main document should also have 404 status. The getStaticProps docs say about the return value:
- notFound - An optional boolean value to allow the page to return a 404 status and page
But in this case the page status is 200 and not 404. Is there something else necessary to do to return status 404?
Without fallback the status is 404.
Share Improve this question edited Sep 17, 2021 at 7:20 juliomalves 50.3k23 gold badges177 silver badges168 bronze badges asked Mar 28, 2021 at 12:39 camcamcamcam 2,6259 gold badges50 silver badges66 bronze badges1 Answer
Reset to default 15For this specific use case you have to use fallback: 'blocking'
instead.
export const getStaticPaths = async () => {
return {
paths: [
{ params: { slug: "a" }},
{ params: { slug: "b" }},
{ params: { slug: "c" }}
],
fallback: 'blocking'
}
}
Unlike fallback: true
, it will not serve a "fallback" version if the page has not been generated yet. That's why you get the 200
status code currently.
Instead, fallback: 'blocking'
will wait for the HTML to be generated before rendering the page - similar to what happens during server-side rendering. This means that if notFound: true
is returned from getStaticProps
you will get the proper 404
status code for the page request.