The utilization of the "notFound" prop within getStaticProps does not influence the HTTP status code returned by the page

I recently set up a fresh Next.js application and created 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
  }
}

Upon navigating to a non-existent page in the browser (e.g. http://localhost:3000/articles/d), it correctly shows the default Next.js 404 page.

However, the network tab in the browser indicates a status 200 for the main document (the 404 error page). The only resources with a status of 404 are d.json and 404.js.

I believe that even the main document should have a 404 status. The getStaticProps documentation mentions the 'notFound' option:

  • notFound - An optional boolean value to allow the page to return a 404 status and page

In this scenario, despite specifying 'notFound', the page still returns a 200 status instead of 404. Is there an additional step required to return a 404 status?

When disabled, the status is indeed 404.

Answer №1

If you are facing this particular scenario, the recommended approach is to use fallback: 'blocking'.

export const getStaticPaths = async () =>  {
  return {
    paths: [
      { params: { slug: "a" }},
      { params: { slug: "b" }},
      { params: { slug: "c" }}
    ],
    fallback: 'blocking'
  }
}

Unlike using fallback: true, this method will not display a "fallback" version if the page has not been generated yet, which explains the 200 status code you are currently experiencing.

By utilizing fallback: 'blocking', the page will wait for the HTML content to be generated before rendering, akin to server-side rendering. Therefore, if notFound: true is returned from getStaticProps, the appropriate 404 status code will be received for the page request.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to create an observable with RXJS that emits only when the number of items currently emitted by the source observables matches?

I am dealing with two observables, obs1 and obs2, that continuously emit items without completing. I anticipate that both of them will emit the same number of items over time, but I cannot predict which one will emit first. I am in need of an observable th ...

How do I test Pinia by calling one method that in turn calls another method, and checking how many times it has been called

As I embark on my journey with Vue 3 and Pinia, a particular question has been lingering in my mind without a concrete answer thus far. Let's delve into the crux of the matter... Here's an example of the store I am working with: import { ref, co ...

View a photo in advance of its upload using VUEjs

Although this question has been raised before, I am struggling with implementing the code in vuejs. Despite my efforts, I have not been able to achieve any results yet. I have included my code below. Could someone please assist me? Here is my code. Thanks ...

Having trouble getting the Socket.io package to install on Node.js in Windows 7?

Hey there! I'm having trouble installing the socket.io module using npm install socket.io. Unfortunately, I encountered the following error: npm WARN package.json <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ee8f80c3869 ...

Error compiling template due to custom component issue

Can you help me troubleshoot my custom component? I'm trying to create a setup with: label input Why am I seeing the error message "idfor is undefined"? And what's causing the issue with labeltext? An unexpected identifier was found in the ...

JQuery Keyup event is not functioning as expected

For my blog navigation, I have set up an event where pressing the 'J' key takes me to the previous post and the 'K' key takes me to the next post. However, I am facing an issue where the event works initially but stops working after the ...

Click to copy: Utilizing Italics in React Components

I've successfully implemented a way to copy text to the clipboard using React. Now, I'm facing the challenge of making only the content of this.state.parties italicized, while keeping the content of this.state.citation non-italicized when pasting ...

JavaScript, keep it easy: globalize

Looking for help with a simple regex expression... document.getElementById('testing').value=f2.innerHTML.replace(">",">\n"); I'm having an issue where it only stops after the first line break. How can I make it work for the enti ...

How to process JSON data that includes a function

I'm trying to replicate a similar diagram using dynamic input data. Here is a basic example of how I'm attempting to achieve this: <script> var myYears = ', 1991, 1992, 1993, 1994, 1995, 1998'; //auto-generated var myValues = ...

My function handler is not being triggered when using React's onClientClick

I'm facing an issue with a button component I have, let's refer to it as < MyButton >. <MyButton onClick={this.props.calculate} onClientClick={this.changeColor} > Calculate </MyButton> Whenever I click the button, my cal ...

Is there a way to automatically recalculate the "Total Price" when the input values are adjusted?

Whenever I add an item to the cart, it gets appended to the row in the shopping cart, and the price adjusts accordingly. However, I'm having trouble getting the price to adjust whenever I change the input values (input type: "number"). I can't se ...

Using a loop to chain jQuery's .when().then() method and ensuring a fixed final call at the end of the

The solution that closely matches my issue can be found at One common use case for .then is chaining ajax requests: $.ajax({...}).then(function(){ return $.ajax({...}); }).then(function(){ return $.ajax({...}); }).then(function(){ retu ...

How can we display a different navbar based on whether the user is logged in or not?

Can anyone share the most effective methods for displaying a different navbar based on whether or not a user is logged in? I have considered a few approaches: One option might involve creating two separate navbars in the HTML file and using CSS to tog ...

Ways to include scrolling specifically for one template

As a newcomer to frontend development, I have recently started learning Vue and the Quasar Framework. I am currently working on a table and trying to set a fixed table name with only the table items scrollable. <template> <q-table virt ...

The division element nested within a select tag

HTML: <div class="row"> <div class="form-group"> <div class="col-xs-10"> <label for="class_code_reservation">Class Code</label> <select type="text" class="form-control" id="class_code_reservation" na ...

Passing large arrays of data between pages in PHP

I'm facing a challenge where I need to pass large arrays of data between pages. Here's the situation: Users input their Gmail login details in a form, which is then sent to an AJAX page for authentication and contact retrieval. If the login fail ...

Using React Native to iterate over a multidimensional array with the array map function

I want to iterate through a two-dimensional array like the one below: var array=[["1"],["3","8"],["4","8","3"],["4","8","3","9"],["1","8","3","9","2"],["6","8","3","9","2","1"],["4","8","3","9","2","11","2"]] Currently, this code only loops through the & ...

NodeJS Exporting Features

A situation is in front of me: var express = require('express'); var router = express.Router(); var articles = require('../model/articles.js'); router.get('/all', function(req, res, next) { res.json(articles.getAll()); ...

Information in a Service is reset upon refreshing the page

After refreshing the page (e.g., by pressing F5), I noticed that the data in my service gets cleared. Is there a way to prevent this issue without using local storage? It's not a critical feature, but it does disrupt the application flow when users re ...

Implementing a password toggle feature on a form that extends Django's default Authentication Form

Incorporating a password toggle feature has become quite the challenge as I extend Django's AuthenticationForm to create my UserLoginForm. Attempting to implement this feature has proven difficult, especially since I have been unable to make use of th ...