next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Next.js default not-found/404 page doesn't render on Vercel deployments

Open ericpesto opened this issue 1 year ago • 15 comments

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/dry-dust-r83nds?file=%2Fnext.config.js%3A10%2C32

To Reproduce

  1. Start the application locally in dev.
  2. Navigate to a page that doesn't exist, i.e. http://localhost:3000/nosuchpage and see Next's default 404 page.
  3. Host the Next.js app on Vercel.
  4. Navigate to a page that doesn't exist, i.e. http://helloworld.com/nosuchpage and we see a broken version of the homepage rather than Next's not-found/404 page.

Current vs. Expected behavior

When navigating to incorrect/non-existent paths, the Next.js default not-found/404 page doesn't render on Vercel deployments, but does during local development.

We would expect to see the 404/not-found page in the Vercel's production deployment, just as we see it in dev.

Verify canary release

  • [X] I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.1.0: Mon Oct  9 21:32:11 PDT 2023; root:xnu-10002.41.9~7/RELEASE_ARM64_T6030
Binaries:
  Node: 21.3.0
  npm: 10.2.4
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 14.0.5-canary.46
  eslint-config-next: 14.0.3
  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)

Not sure, App Router, Middleware / Edge (API routes, runtime), Routing (next/router, next/navigation, next/link)

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

Vercel (Deployed)

Additional context

We are hosting our Next.js app on Vercel.

As per these Next.js docs we have also tried making our own not-found.tsx component and placed it under ./app so all incorrect paths should result in the custom 404 being displayed, but they don't on Vercel, but do during local development. As suggested in other threads, we have also tried placing it throughout the application, but with no with success.

Note: running in production mode locally still gives a 404

ericpesto avatar Jan 10 '24 15:01 ericpesto

@ericpesto I have thoroughly investigated the reported issue, and it appears to be related to deployment on Vercel rather than a 404 error. Upon closer inspection, I noticed that some files crucial for your project are missing, specifically those that you are attempting to import.

It seems that when you pushed the repository to GitHub, an empty folder structure may have been created. GitHub typically does not support an empty folder structure unless it contains at least one file. Consequently, when deploying this project on Vercel, an error arises due to the absence of necessary files.

To address this issue, I recommend ensuring that the repository on GitHub includes the required files within the folder structure before attempting the deployment on Vercel. This should resolve the error encountered during the deployment process. If you have any further questions or need assistance with this matter, please feel free to reach out. image

ianujvarshney avatar Jan 11 '24 06:01 ianujvarshney

My project is closed source and as such I can't provide the offending code/repo, building a like for like project in code sandbox to replicate the issue would take a fair bit of time.

On our end we have no problem deploying on Vercel, we can see the site live with no errors. The issue is that our 404 pages don't render for the site hosted on Vercel when incorrect urls paths are specified, whereas they do when running the project locally

ericpesto avatar Jan 11 '24 11:01 ericpesto

Could this be related to:

https://github.com/vercel/next.js/issues/52765 https://github.com/vercel/next.js/issues/54239

None of the suggested 'work-arounds' fix the issue for me.

lee-broadley avatar Jan 11 '24 11:01 lee-broadley

Project Settings / Change Framework preset from Other to Next.js Redeploy the project.

pumkindev avatar Jan 14 '24 13:01 pumkindev

Our framework preset already is set to Next.js on the Vercel Dashboard

ericpesto avatar Jan 15 '24 10:01 ericpesto

Add a custom 404 page this should fix the problem or an empty 404 page

pumkindev avatar Jan 19 '24 19:01 pumkindev

We did try this, see above:

As per these Next.js docs we have also tried making our own not-found.tsx component and placed it under ./app so all incorrect paths should result in the custom 404 being displayed, but they don't on Vercel, but do during local development. As suggested in other threads, we have also tried placing it throughout the application, but with no with success.

ericpesto avatar Jan 25 '24 15:01 ericpesto

I had a similar issue with App router only code. My workaround was to force 404 page based on the pathname:

// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

// the following code is taken from: https://nextjs.org/docs/app/building-your-application/routing/middleware#setting-headers
export function middleware(request: NextRequest) {
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set("x-pathname", request.nextUrl.pathname);

  return NextResponse.next({
    request: { headers: requestHeaders },
  });
}

// the following code has been copied from https://nextjs.org/docs/app/building-your-application/routing/middleware#matching-paths
export const config = {
  matcher: [
    /*
     * Match all request paths except for the ones starting with:
     * - api (API routes)
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico (favicon file)
     */
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
  ],
}

// app/page.tsx
import { headers } from 'next/headers';
import { notFound } from "next/navigation";

export default async function Page() {
  const pathname = headers().get("x-pathname");
  if (pathname !== "/") return notFound();
   
  return <>{/*... your page code */}</>
}

andremendonca avatar Jan 31 '24 16:01 andremendonca

Any fix to this solution, having the same issue. I have not-found.tsx file in the app directory, works when run locally, but it never gets rendered in production for incorrect url?

mughalhsm avatar Apr 21 '24 23:04 mughalhsm

Redeploying doesn't make the problem gone. But in development server, the 404 page is doing its work.

devsujay19 avatar May 20 '24 10:05 devsujay19

this worked for me

inside app create a file at [...not_found]/page.tsx

import {notFound} from "next/navigation"

export default function NotFoundCatchAll() {
  notFound()
}

Reason: Since dynamic routes are resolved after static routes, we can solve it by creating a dynamic catch-all route using a [...not_found] folder and add it to our app folder.

kunal-dario avatar Jun 07 '24 11:06 kunal-dario

This is still an issue for me as well. I have app/not-found.js, app/error.js amd app/global-error.js which work fine of dev, but after deployment on Vercel production I keep getting a very mixed experience:

  1. root/not_existing_link - returns default Next 500 page instead of my custom 404
  2. root/something_that_exists/not_existing_link - returns my custom 404 page as expected

I have only one dynamic route under app/[slug]. Adding aforementioned [...not-found] didn't help.

Any other suggestions?

eagrigorev avatar Jun 16 '24 11:06 eagrigorev

I have the same issue. A dynamic route that is using generateStaticParams will show the correct custom 404 page when a path does not exists. But when visiting other routes that not exists in the application the Vercel 404 page is shown.

I have one dynamic route in app/[post]/page.js. 404's in this route shows the correct custom 404 page but other routes (for example /something/something-else) shows the default Vercel 404.

lejtzen avatar Jun 27 '24 14:06 lejtzen

I have the same issue. A dynamic route that is using generateStaticParams will show the correct custom 404 page when a path does not exists. But when visiting other routes that not exists in the application the Vercel 404 page is shown.

I have one dynamic route in app/[post]/page.js. 404's in this route shows the correct custom 404 page but other routes (for example /something/something-else) shows the default Vercel 404.

Good day, If you want your not-found.js page to catch all the 404's of your application, place that file in the root of app directory. Also, on prod deployment you may also want to add export const dynamicParams = false; after the generateStaticParams call in your [post] segment route. That will tell next/vercel to render 404's instead of trying to find the non-existing page in the static routes and throw 500 error after not finding it.

Hope that helps! :)

eagrigorev avatar Jul 03 '24 18:07 eagrigorev

Add a custom 404 page this should fix the problem or an empty 404 page

It is not solving the problem.

devsujay19 avatar Jul 04 '24 09:07 devsujay19

@eagrigorev

My file structure:

  • app
    • [post]
      • page.js
    • not-found.js

Good day, If you want your not-found.js page to catch all the 404's of your application, place that file in the root of app directory.

I have a not-found.js in the app directory but this is only shown on "defined routes" such as [post]. On other routes (such as /something/something-else) a Vercel 404 is shown.

Also, on prod deployment you may also want to add export const dynamicParams = false; after the generateStaticParams call in your [post] segment route. That will tell next/vercel to render 404's instead of trying to find the non-existing page in the static routes and throw 500 error after not finding it.

This does not matter. If someone is getting 500 error here it probably something else. Maybe generateMetadata function. For me it's fine to try generating pages that did not exists while building.

lejtzen avatar Jul 05 '24 07:07 lejtzen

@lejtzen

I have the same structure, and it works fine for me, every route, even something/something/something-else is getting tracked by not-found.js. Maybe we have some other differences in the code? In my [post] page I explicitly check condition when nothing found in defined routes and return notFould(). I also have export const dynamicParams = false; in the end of the file.

You can check my [post] page.js here and compare it to yours: https://github.com/eagrigorev/eagrigorev-website/blob/master/src/app/%5Bslug%5D/page.js

Hope that will help :)

eagrigorev avatar Jul 05 '24 07:07 eagrigorev

not-found page in root directory (app) works fine, but the issue occurs in dynamic route.

  • app
    • profile
      • [id]
        • page
        • error
        • layout
      • not-found
    • not-found

Inside page I'm fetching user by id. If user has not been found fetch function throws error, then error page catches this error and returning notFound()

page.tsx

export default async function ProfilePage({ params }: ProfilePageProps) {
  const userId = validateId(params.id)

  const token = await getServerToken()

  if (!token) redirect('/')

  const { profile } = await getUser(token, { userId })

  return (
    <ProfileCard {...profile}>
      <Playback />
    </ProfileCard>
  )
}

error.tsx

export default function ProfileError({ error, reset }: ErrorProps) {
  if (error.message === 'The access token expired') reset()

  if (
    error instanceof Error &&
    [VALIDATION_FAILED_UUID_EXPECTED, USER_NOT_FOUND].includes(error.message)
  )
    return notFound()

  console.error(error)
}

Everything works on development, the issue occurs on production. Not found page is not rendered, instead I'm getting console errors.

Error: An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.
Error: invariant expected app router to be mounted
Error: Minified React error #419; visit https://react.dev/errors/419 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

Mnigos avatar Jul 10 '24 10:07 Mnigos