skip to Main Content

The point of choosing Nextjs was for SSR and SEO. We have an external REST API which we query for data on the frontend. But on some pages, we need do a pre-render fetching and display proper 404 Not Found header when API returns 404. This seems to be difficult for me.

The app structure looks like this:

app/p/auth/
├── layout.jsx
├── loading.jsx
├── password-reset
│   └── [key]
│       ├── components
│       │   ├── index.js
│       │   ├── ResetPassword.jsx
│       │   └── SecurityQuestions.jsx
│       ├── page.jsx
│       └── ResolveComponent.jsx
├── reset-successful
│   └── page.jsx
└── sign-up
    └── page.jsx

My Problem

A request is being made to http://example.com/p/auth/password-reset/[key] . The key is to be captured and sent to the REST API to validate. If not found, and notFound() is thrown, it should return a proper 404 HTTP response.

What I have tried

With what I have tried, the only way that works to return a proper 404 header is by throwing notFound() in app/p/auth/layout.jsx, but the problem is, the layout is shared amongst other paths (e.g. app/p/auth/sign-up), and I cannot isolate the request in the app/p/auth/layout.jsx

I have tried to isolate the layout.jsx by deleting the app/p/auth/layout.jsx and re-creating one in each of the paths, but throwing notFound() inside app/p/auth/password-reset/[key]/layout.jsx does not set 404 HTTP header. It returns 200 and further more loads to 404 page.

notFound() sets 404 header when called in app/p/auth/layout.jsx but when isolating the layout to sub-folder like app/p/auth/password-reset/[key]/layout.jsx, it doesn’t set 404 header but it loads 404 page with 200 header. What is the proper way to handle this?

2

Answers


  1. A solution mentioned here is to set the status code explicitly, by doing:

    • In middleware.tsx do condition check for /404 pathname and set 404 status
    • Create /app/404/page.tsx (if needed)

    Your middleware would look something like:

    export function middleware(req) {
    const url = req.nextUrl;
    
    if (url.pathname === '/404') {
       return  NextResponse.next({
       status: 404,
      });
     }
     return NextResponse.next();
    }
    
    Login or Signup to reply.
  2. make sure you have app/not-found.tsx which handles notFound(), non-existing routes and /404

    few solutions I came up while encountering this issue:

    • in middleware.ts file, return NextResponse.rewrite(new URL('/404', req.url))
    • redirect('/404')
    • check if in file app/layout.tsx, child components are wrapped in <Suspense> – if yes, remove global Suspense
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search