Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
1 task done
ericpesto opened this issue Jan 10, 2024 · 18 comments
Open
1 task done
Labels
bug Issue was opened via the bug report template. Navigation Related to Next.js linking (e.g., <Link>) and navigation. Runtime Related to Node.js or Edge Runtime with Next.js.

Comments

@ericpesto
Copy link

ericpesto commented Jan 10, 2024

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

  • 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 ericpesto added the bug Issue was opened via the bug report template. label Jan 10, 2024
@github-actions github-actions bot added Runtime Related to Node.js or Edge Runtime with Next.js. Navigation Related to Next.js linking (e.g., <Link>) and navigation. labels Jan 10, 2024
@ianujvarshney
Copy link

ianujvarshney commented Jan 11, 2024

@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

@ericpesto
Copy link
Author

ericpesto commented Jan 11, 2024

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

@lee-broadley
Copy link

Could this be related to:

#52765
#54239

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

@pumkindev
Copy link

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

@ericpesto
Copy link
Author

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

@pumkindev
Copy link

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

@ericpesto
Copy link
Author

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.

@andremendonca
Copy link

andremendonca commented Jan 31, 2024

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 */}</>
}

@mughalhsm
Copy link

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?

@devsujay19
Copy link

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

@kunal-dario
Copy link

kunal-dario commented Jun 7, 2024

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.

@eagrigorev
Copy link

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?

@lejtzen
Copy link

lejtzen commented Jun 27, 2024

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.

@eagrigorev
Copy link

eagrigorev commented Jul 3, 2024

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! :)

@devsujay19
Copy link

devsujay19 commented Jul 4, 2024

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

It is not solving the problem.

@lejtzen
Copy link

lejtzen commented Jul 5, 2024

@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.

@eagrigorev
Copy link

@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 :)

@Mnigos
Copy link

Mnigos commented Jul 10, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. Navigation Related to Next.js linking (e.g., <Link>) and navigation. Runtime Related to Node.js or Edge Runtime with Next.js.
Projects
None yet
Development

No branches or pull requests