node.jsreactjshttpnext.js

How to set status code 404 instead of 200 for 404-page in Next.js


I have inquired about the way of setting 404 status code to 404-page in Next.js but the response I was given was that this is not true, that the status code is 404 by default. I was not able to present print screens in the comment, so I want to present them here, and possibly get the answer I am after. Truth is that all the bad requests have status code of 404, but the 404-page itself has status 200enter image description here as you can see, the first two positions are with status code 200. I want to trigger 404 every time the url does not match a page in my pages directory, but to be returned with status code 404 instead of 200. Or if this is possible I would prefer to have it redirected with status code 301 to page 404, and the url after redirect to be eg. /404?url=%2Fbadrequest. Would you please at least point me in the direction. I don't know whether it should be done client or server side. I imagine I need to react server side to set the proper response code, but how? And to redirect and build up an url like /404?url=%2Fbadrequest does it have to be done client or server side?

Many thanks


Solution

  • The first two requests you are referring to are script and fetch/XHR requests not the page (see Type, it will be document for pages; alternatively you can select "Doc" in filters). The page (/badrequest) is requested in the last request in your image (and responded with 404 status code). Those JS files are just used to render the 404 error component.

    For the redirect part you can do something like this:

    // pages/[...slug].js
    
    const Fake = () => <></>;
    export default Fake;
    
    const getServerSideProps = async ({ req }) => {
      return {
        redirect: {
          destination: `/404?url=${encodeURI(req.url)}`,
          permanent: true
        }
      };
    };
    
    export { getServerSideProps };
    
    // pages/404.js
    
    import { useRouter } from "next/router";
    import { useEffect, useState } from "react";
    
    const ErrorPage = () => {
      const { asPath: path } = useRouter();
      const [currentPath, setCurrentPath] = useState("");
    
      useEffect(() => {
        setCurrentPath(
          decodeURI(
            new URLSearchParams(path.replace(/^.*?\?/, "")).get("url") || ""
          )
        );
      }, [path]);
    
      return <div>{currentPath} Not Found</div>;
    };
    
    export default ErrorPage;
    

    Result:

    Code Sandbox: codesandbox.io/s/bitter-glade-btrcp


    PS: Status code 308 means "Permanent Redirect"

    If you want 301 status code, then change pages/[...slug.js] to this:

    const Fake = () => <></>;
    export default Fake;
    
    const getServerSideProps = async ({ req, res }) => {
      res.writeHead(301, { location: `/404?url=${encodeURI(req.url)}` }).end();
      return { props: {} };
    };
    
    export { getServerSideProps };
    

    I've updated the sandbox accordingly.