next.js: Add a way to set the status code in getServerSideProps

Feature request

When the API call in getServerSideProps returns a 404 or null, I want the route to 404 in the website. I want to be able to manually tell getServerSideProps that an error has occurred and to render a specific status code.

I searched the docs, tried calling res.status(404) and it didn’t work, so I’m filing this feature request

Describe the solution you’d like

The 2nd solution probably fits best from an API design perspective with the rest of Next.js, but the first is probably what most JS developers would expect

Ideal solution

Inside getServerSideProps, if I call res.status(404), the Network tab should show the current document’s status is 404 and the Next.js would render _error or next/error instead of the page it was going to render.

This is ideal, for me at least, because this requires nothing new to learn. It’s how I expected it to work before I filed this issue. However, this might not make as much sense in other cases (getStaticProps).

Alternative solution

Add statusCode to the object we return in getServerSideProps.

For example:

export const getServerSideProps = async ({ query: { id: username }, res }) => {
  const profile = await fetchProfileByUsername(username);
  const profileId = profile?.id ?? null;

  return {
+   statusCode: profileId ? 200 : 404,
    props: {
      profile,
      profileId: profile?.id ?? null,
      username
    }
  };
};

When the status code is > 299, render the appropriate error page with the status code, but default it to 200

Another alternative solution

When you want to manually trigger a 404 error in Ruby on Rails, you raise ActionController::RoutingError inside your controller, for example:

raise ActionController::RoutingError.new('Not Found')

A Next.js version of that might look like this:

import {NotFoundError} from 'next/error';

export const getServerSideProps = async ({ query: { id: username }, res }) => {
  const profile = await fetchProfileByUsername(username);
  const profileId = profile?.id ?? null;
  
   if (!profileId) {
     throw new NotFoundError();
   }

  return {
    props: {
      profile,
      profileId: profile?.id ?? null,
      username
    }
  };
};

This would naturally mean you could render the 404 page easily from non-page parts of your app, too.

My personal preference is I don’t like throwing errors this way, so I put it at the end. But that’s just my opinion

Describe alternatives you’ve considered

I can do this right now, however the status code it returns is still 200 when it really should 404.

import * as React from "react";
import { Page } from "../../src/components/Page";
import { fetchProfileByUsername } from "../../src/lib/api";
import NotFoundPage from "../404";

export const getServerSideProps = async ({ query: { id: username }, res }) => {
  const profile = await fetchProfileByUsername(username);

  return {
    props: {
      profile,
      profileId: profile?.id ?? null,
      username
    }
  };
};

export const ShowProfilePage = ({ profile, username, profileId }) => {
  if (!profile || !profileId) {
    return <NotFoundPage statusCode={404} />;
  }
  return (
    <Page header={<div className="Header-title">{username}</div>}>
      {...notRelevantToCodeSnippet}
    </Page>
  );
};

export default ShowProfilePage;

Additional context

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 17
  • Comments: 25 (5 by maintainers)

Most upvoted comments

This has been solved in Next.js 10: https://nextjs.org/blog/next-10#notfound-support

Doesn’t res has a statusCode property that you can set?

export const getServerSideProps = async ({ res }) => {
  res.statusCode = 404
  return {
    error: 'oops'
  };
};

For anyone that has found this page looking at how to redirect in getServerSideProps, the code on this page seems to be outdated and did not work for me.

This, however, worked:

export const getServerSideProps = async ({ res }) => {
  res.statusCode = 404
  res.end();
  return {
    props: {
       error: 'oops'
    }
  };
};

@timneutkens What if I want to set other than 404 and without redirection?

Yes, @shobhitsharma for example I would like to return a 403 when someone is not allowed to see my sitemap, not a 404 😃

Doesn’t res has a statusCode property that you can set?

export const getServerSideProps = async ({ res }) => {
  res.statusCode = 404
  return {
    error: 'oops'
  };
};

Shouldn’t It be

return {
    props: { 
      error: 'oops' 
    }
};

Cuz it throws additional keys were returned from getServerSideProps. Properties intended for your component must be nested under the props key,

Oh, my code was wrong – it returns 404 now. Thanks for the example @claus.

In that case, maybe the ask here is:

  1. Consider adding a note in the docs for getServerSideProps on how to set a status code on the res object
  2. Consider rendering the <Error /> page by default when res.statusCode is a non-200 number. This would be a breaking change though, so making it a default is questionable.

One interesting thing Rails does to make it easier to ship breaking changes: config/application.rb has a config.load_defaults(6.0) function included in every rails app. It loads defaults for a specific version of Rails (6.0), so that if they decide to change defaults later, it makes it easier to upgrade

For anyone that has found this page looking at how to redirect in getServerSideProps, the code on this page seems to be outdated and did not work for me.

This, however, worked:

export const getServerSideProps = async ({ res }) => {
  res.statusCode = 404
  res.end();
  return {
    props: {
       error: 'oops'
    }
  };
};

Thanks. It’s at least working on Next.js v9.5.2. if not add res.end() , Nextjs will keep trying to render the page. However, with this method Error Page Redirecting will failed.

I’ll be honest I’m still very confused on how to redirect to an error page, but at least this solution pleases google.

An official docs page would be great, cause there’s clearly not enough information…

Thanks for mention. I’ve googled the resolution but many of them handle the error in Page Render Function, which is not gracefully to me. In my opinion Nextjs should take care of things like this, and getServerSiteProps() has enough space to both support error handling and keep its backward capability.

For anyone that has found this page looking at how to redirect in getServerSideProps, the code on this page seems to be outdated and did not work for me.

This, however, worked:

export const getServerSideProps = async ({ res }) => {
  res.statusCode = 404
  res.end();
  return {
    props: {
       error: 'oops'
    }
  };
};

Thanks. It’s at least working on Next.js v9.5.2. if not add res.end() , Nextjs will keep trying to render the page. However, with this method Error Page Redirecting will failed.

I’ll be honest I’m still very confused on how to redirect to an error page, but at least this solution pleases google.

An official docs page would be great, cause there’s clearly not enough information…

In Next v 9.5.3 it seems you no longer need res.end() at least it’s working for me without it.

export const getServerSideProps = async ({ res }) => {
  res.statusCode = 404
  return {
    props: {
       error: 'oops'
    }
  };
};

When I use Link from ‘next/link’ to navigate to a page which has this getServerSideProps with custom res.statusCode set, page is fully refreshed. Does anybody also have that issue?