vercel / next.js

The React Framework
https://nextjs.org
MIT License
123.38k stars 26.32k forks source link

Custom 404 not working in Pages Router if `app` directory exists #58945

Open ajmnz opened 7 months ago

ajmnz commented 7 months ago

Link to the code that reproduces this issue

https://github.com/ajmnz/next-custom-404-repro

To Reproduce

  1. Install deps (npm i), start the dev server (npm run dev) and navigate to localhost:3000
  2. Follow the instructions shown

Current vs. Expected behavior

I expected Next.js to detect that I'm working with the Pages Router instead of assuming I'm using the App Router just because there's a directory called app.

When an app directory is present, Next.js will output ○ Compiling /not-found .... If renamed, it will change to ○ Compiling /404 ..., which is the expected behavior.

Verify canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: x64
  Version: Darwin Kernel Version 22.6.0: Wed Oct  4 21:25:26 PDT 2023; root:xnu-8796.141.3.701.17~4/RELEASE_X86_64
Binaries:
  Node: 20.8.0
  npm: 10.1.0
  Yarn: 1.22.10
  pnpm: N/A
Relevant Packages:
  next: 14.0.3
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.2
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Routing (next/router, next/navigation, next/link)

Additional context

I believe the offending release is between 13.3.4 and 13.5.4 (inclusive). I have an app on 13.3.4 with the same setup described (pages router and a directory called app) and custom 404s are working just fine.

mohamedsalem331 commented 7 months ago

@ajmnz I believe the answer for your problem is in docs here

ajmnz commented 7 months ago

@ajmnz I believe the answer for your problem is in docs here

No, this is about using the Pages Router and having a directory called app which should not be picked up as the App Router.

BowlingX commented 7 months ago

I can confirm the issue in dev mode, although if you create a production build, it will use the 404.tsx.

renovatt commented 7 months ago

I have the same problem, not-found.tsx in development mode is not working inside the app folder in version 14.0.1+, but it is working in build/deploy.

yournatalita commented 7 months ago

I experience the same issue. While using app and pages folder at the same time, custom pages/404.txt doesn't work in development mode. In my case, app is used for API routes only (app/api/...), while all pages kept in pages folder.

Version 13.5.4

anksuthar commented 7 months ago

Same issue with me any one find the solution While all pages kept in pages folder 404 page and other static pages not working after version change of next js Version 13.4.x to Version 13.5.x

jzxhuang commented 6 months ago

Bumping this: this issue is not isolated to the dev server, it also occurs in production builds as of 14.0.5-canary.40. Here's a repro and some observations: https://github.com/jzxhuang/next-404-pages-router-repro

This is problematic because it makes it difficult to migrate from pages -> app router. Our app does not work with app router at all atm. We want to incrementally migrate while keeping all routes in pages/ including our 404 page. With this issue, we can't do that at all...


UPDATE: Oddly enough, the behaviour is different when deployed on Vercel vs locally. Locally, I'm running pnpm build && pnpm start. On Vercel though, we see the 404 page from pages/ router served...

here is the deploy: https://next-404-pages-router-repro.vercel.app/asldkf

Interestingly, the Vercel build logs seem to indicate that the app router's "not-found" should be served, so there must be some difference in the Vercel Next.js runtime compared to next start?

image

benWozak commented 2 months ago

Still having this issue in production build v14.1.4.

not-found.tsx works in local but not in production.

emkr commented 2 months ago

Ran into the same issue, removing the 404.js from with in pages/ didn't fix our issue, I kept getting a 307 redirect issue. We have a [slug] route in our pages/ and it appears that's where it was getting caught.

Only way that we are able to mitigate the error, is by adding a check in the middleware for 404 and returning a NextResponse.error. Only way I was able to consistently get the not-found.tsx file to show. Not the cleanest solution but it's unblocked us.

devsujay19 commented 2 months ago

I have the same problem, not-found.tsx in development mode is not working inside the app folder in version 14.0.1+, but it is working in build/deploy.

But I've the opposite issue, the not-found.tsx page in the app directory is working completely good as expected but in the deployment on Vercel, the page isn't rendering but instead, the DEPLOYMENT_NOT_FOUND page from Vercel is rendering. I tried redeploying the project, but it occuring every time. I' using the 14.2.3 of NextJS.

ss-ravi commented 2 months ago

I'm also facing the same problem. my workaround is to add a [slug].tsx in the root of the pages folder with the 404 page. is there any problems or things I should be aware by using this workaround?

Princejain21 commented 1 month ago

is there anyone who resoved this error 404 not found.

devsujay19 commented 1 month ago

is there anyone who resoved this error 404 not found.

For now, no one has done that.

sorinalinpavel commented 1 month ago

If you will follow the example in the intl https://github.com/amannn/next-intl/blob/main/examples/example-app-router-playground/src/app/not-found.tsx you will see that they are giving a nice way to handle it.

Also, keep in mind that your pages/404 will not be needed, because when you have the app folder, you will also route the 404 there.

Inside the app folder, create a catch-all route and just all the notFound to make sure that you are serving correctly the 404 for all the routes.

So, in order to solve it, what you need to do it to:

  1. app/layout.tsx
  2. app/not-found.tsx
  3. app/[...not-found] or app/[locale]/[...not-found]/page.tsx where you will just do:
import { notFound } from 'next/navigation'

export default function CatchAllPage () {
  notFound()
}
  1. delete the pages/404.tsx

Also, as a side note, make sure that you are not calling the notFound() inside the pages/ because it is not supported and you have to use the

return {
  notFound: true
}

For me, even the dynamic pages are correctly handled now using intl, app and pages together.

Above fix has been testes with Next 14.1.4 and next intl 3.11.1

devsujay19 commented 1 month ago

The issue is occuring in the canary and 14th release of Next. I made my portfolio with Next 13. Both development and deployed servers are rendering the 404 page (the default one from Next app).

masoudfallahi commented 2 weeks ago

If you will follow the example in the intl https://github.com/amannn/next-intl/blob/main/examples/example-app-router-playground/src/app/not-found.tsx you will see that they are giving a nice way to handle it.

Also, keep in mind that your pages/404 will not be needed, because when you have the app folder, you will also route the 404 there.

Inside the app folder, create a catch-all route and just all the notFound to make sure that you are serving correctly the 404 for all the routes.

So, in order to solve it, what you need to do it to:

  1. app/layout.tsx
  2. app/not-found.tsx
  3. app/[...not-found] or app/[locale]/[...not-found]/page.tsx where you will just do:
import { notFound } from 'next/navigation'

export default function CatchAllPage () {
  notFound()
}
  1. delete the pages/404.tsx

Also, as a side note, make sure that you are not calling the notFound() inside the pages/ because it is not supported and you have to use the

return {
  notFound: true
}

For me, even the dynamic pages are correctly handled now using intl, app and pages together.

Above fix has been testes with Next 14.1.4 and next intl 3.11.1

I did it, but it didn't work for me.