Next.js Discord

Discord Forum

Missing /_not-found/page: /_not-found with app router

Answered
Barbary Lion posted this in #help-forum
Open in Discord
Avatar
Barbary LionOP
So I am trying to build my project with i18n internationalization and it seems to stop compiling because it can't find the _not-found.tsx. Not matter where in the app directory I put the file, it will not find it. But as soon as I put it in the pages directory (even though I am using app directory) it will complain about a conflict with some not-found file in next/dist/client/components/... . This is the same for the error routes, but these don't have conflicts in the pages directory.
Answered by Anay-208
-# app/not-found.tsx
'use client';
 
import Error from 'next/error';
import { redirect } from 'next/navigation';
 
export default function NotFound() {
  // redirect('/'); // Add this(if needed) after commenting use client and the return statement
  return ( 
    <html lang="en">
      <body>
        <Error statusCode={404} />
      </body>
    </html>
  );
}


-# app/layout.tsx
import React from "react";


export default async function RootLayout({ children } : { children: React.ReactNode}) {
    return (
        <>
        {children}
        </>
    )
}


Copy same error.tsx in app/ folder from app/[locale]

app/[locale]/not-found.tsx remains same

Comment WebPack config(to be fixed)
View full answer

86 Replies

Avatar
Is this your file structure @Barbary Lion ?
app
|-- [lang]
    |-- page.tsx       // Main page for locale
    |-- not-found.tsx  // Not Found page for locale
    |-- error.tsx      // Error boundary for locale segment
|-- global-error.tsx   // Global error for the entire app
|-- layout.tsx         // Global layout
|-- page.tsx           // Root page
Avatar
Barbary LionOP
This is my current tree:
├───app
    _not-found.tsx (will not be found)
│   └───[locale]
│       ├───about
│       ├───blog
│       │   └───blogs
│       ├───buildattack
│       ├───dashboard
│       │   ├───post-its
│       │   └───scheduler
│       ├───help-feedback
│       ├───hooks
│       ├───login
│       ├───logout
│       ├───profile
│       ├───projects
│       ├───settings
│       ├───[...rest]
        ├───_not-found.tsx (will not be found)
        ├───providers.tsx //i18n configuration
        ├───layout.tsx //Root layout
        └───page.tsx //Root page
├───components
│   ├───blog
│   ├───cards
│   ├───dashboard
│   └───login
├───config
├───i18n
├───pages
  _error.tsx
  _not-found.tsx (will result in conflict)
└───styles
@Anay-208
Avatar
you made a typo, its _not-found.tsx
its just not-found.tsx
Avatar
Barbary LionOP
Oh yeah. that is me typing it in here
Avatar
not even underscore is needed before
remove underscore
Avatar
Barbary LionOP
The file in my IDE is correctly spelled but my tree doesn't show files
Avatar
before
Avatar
Barbary LionOP
okay one sec removing underscore
Removing _ outside of the [locale] will result in this (If I add the layout it will get treated as a normal page and it will return to the old error.

Having not-found.tsx in my [locale] folder, it will go back to showing this error on build:
> Export encountered errors on following paths:
        /_not-found/page: /_not-found
Image
I had the same issue with error.tsx and the only way to make it work is to add it into the pages directory
Avatar
remove not-found.tsx from app folder, and put it inside locale only
Avatar
Barbary LionOP
I can't add the _not-found.tsx there though, because I run into a conflict
it is
Avatar
In this structure, your _not-found.tsx is inside app folder. put it inside [locale] folder.
this is what this err is indicating
Avatar
Barbary LionOP
This is my current tree:
├───app
│   └───[locale]
│       ├───about
│       ├───blog
│       │   └───blogs
│       ├───buildattack
│       ├───dashboard
│       │   ├───post-its
│       │   └───scheduler
│       ├───help-feedback
│       ├───hooks
│       ├───login
│       ├───logout
│       ├───profile
│       ├───projects
│       ├───settings
│       ├───[...rest]
        ├───not-found.tsx (will not be found)
        ├───providers.tsx //i18n configuration
        ├───layout.tsx //Root layout
        └───page.tsx //Root page
├───components
│   ├───blog
│   ├───cards
│   ├───dashboard
│   └───login
├───config
├───i18n
├───pages
  _error.tsx
└───styles

This is the layout now. The not-found.tsx is inside [locale] and it is not being found. I get
> Export encountered errors on following paths:
        /_not-found/page: /_not-found

If I put the _ infront, same thing
Avatar
whats your nextjs version?
Avatar
Barbary LionOP
14.2.5
Avatar
can you send your not-found.tsx file?
Avatar
Barbary LionOP
export const dynamic = "force-dynamic";
import { redirect } from "next/navigation";

export default function _notFound() {
  redirect("/");
  return <div></div>;
}
Should I try and use NotFound() as the function to export?
Avatar
Yup, its happening because not-found.tsx is not expecting to redirect.
Can you try removing redirect first
Avatar
Barbary LionOP
The file is in the pages directory currently. Or do you want me to put it back into [locale]?
Avatar
Yes
Image
Ai genereted answer, could be wrong
put back into locale, and remove redirect
Avatar
Barbary LionOP
ye I already consoulted them too I tried almost everything from the docs
lol
Okay
so
Avatar
is it working/
Avatar
Barbary LionOP
neither this
export const dynamic = "force-dynamic";
import { redirect } from "next/navigation";

export default function NotFound() {
  return <div></div>;
}

nor the same with _notFound() works
So as far as I can tell is, that it is trying to find not-found.tsx in the pages directory
which shouldn't be a thing since I am using app directory
Avatar
Can you try commenting export const dynamic?

And in div, just add not found
Avatar
Barbary LionOP
The same happened to error.tsx but that one doesn't conflict
I think export const dynamic is already there... But i will add the text
Ye still not finding the file
Avatar
commenting*
Avatar
Barbary LionOP
Here is the full error:
Image
Error if I put it in the pages folder (with _ notation):

 ⨯ Conflicting app and page file was found, please remove the conflicting files to continue:
 ⨯   "pages/_not-found.tsx" - "next/dist/client/components/not-found-error"
Also commenting doesn't change it
Avatar
For now, just don't even use pages dir
delete pages dir completely, it won't help at all
And can you send your layout file?
Avatar
Barbary LionOP
This will add two new problems;
> Export encountered errors on following paths:
        /_error: /404
        /_error: /500
        /_not-found/page: /_not-found

because the pages directory contained the _error.tsx (I have a seperate error.tsx in the app directory under [locale] but same as with the not-found it will not get registered.
Top layout.tsx:

import "@/src/styles/globals.css";
import { Metadata, Viewport } from "next";
import { Link } from "@nextui-org/link";
import clsx from "clsx";

import { Providers } from "./providers";

import { siteConfig } from "@/src/config/site";
import { fontSans } from "@/src/config/fonts";
import { Navbar } from "@/src/components/navbar";


import { config } from '@fortawesome/fontawesome-svg-core'
import '@fortawesome/fontawesome-svg-core/styles.css'
import { getMessages } from "next-intl/server";
import { NextIntlClientProvider } from "next-intl";
config.autoAddCss = false

export const metadata: Metadata = {
  title: {
    default: siteConfig.name,
    template: `%s - ${siteConfig.name}`,
  },
  description: siteConfig.description,
  icons: {
    icon: "/favicon.ico",
  },
};

export const viewport: Viewport = {
  themeColor: [
    { media: "(prefers-color-scheme: light)", color: "white" },
    { media: "(prefers-color-scheme: dark)", color: "black" },
  ],
};

export default async function RootLayout({
  children,
  params: {locale}
}: {
  children: React.ReactNode;
  params: {locale: string}
}) {
  const messages = await getMessages();
  return (
    <html suppressHydrationWarning lang={locale}>
      <body
        className={clsx(
          "min-h-screen bg-background font-sans antialiased",
          fontSans.variable,
        )}
      >
        <Providers themeProps={{ attribute: "class", defaultTheme: "dark" }}>
          <NextIntlClientProvider messages={messages}>
            <div className="relative flex flex-col h-fit bg-main light:bg-light overflow-x-hidden scrollbar-hide">
              <Navbar />
              <main className="container mx-auto max-w-fit flex-grow h-fit z-0 scrollbar-hide">
                {children}
              </main>
            </div>
          </NextIntlClientProvider>
        </Providers>
      </body>
    </html>
  );
}
Avatar
Just for testing, can you comment the next intl and provders part & check if it is working?
Avatar
Barbary LionOP
import "@/src/styles/globals.css";
import { Metadata, Viewport } from "next";
import { Link } from "@nextui-org/link";
import clsx from "clsx";

import { Providers } from "./providers";

import { siteConfig } from "@/src/config/site";
import { fontSans } from "@/src/config/fonts";
import { Navbar } from "@/src/components/navbar";


import { config } from '@fortawesome/fontawesome-svg-core'
import '@fortawesome/fontawesome-svg-core/styles.css'
import { getMessages } from "next-intl/server";
import { NextIntlClientProvider } from "next-intl";
config.autoAddCss = false

export const metadata: Metadata = {
  title: {
    default: siteConfig.name,
    template: `%s - ${siteConfig.name}`,
  },
  description: siteConfig.description,
  icons: {
    icon: "/favicon.ico",
  },
};

export const viewport: Viewport = {
  themeColor: [
    { media: "(prefers-color-scheme: light)", color: "white" },
    { media: "(prefers-color-scheme: dark)", color: "black" },
  ],
};

export default async function RootLayout({
  children,
  params: {locale}
}: {
  children: React.ReactNode;
  params: {locale: string}
}) {
  const messages = await getMessages();
  return (
    <html suppressHydrationWarning lang={locale}>
      <body
        className={clsx(
          "min-h-screen bg-background font-sans antialiased",
          fontSans.variable,
        )}
      >
        <Providers themeProps={{ attribute: "class", defaultTheme: "dark" }}>
        
            <div className="relative flex flex-col h-fit bg-main light:bg-light overflow-x-hidden scrollbar-hide">
              <Navbar />
              <main className="container mx-auto max-w-fit flex-grow h-fit z-0 scrollbar-hide">
                {children}
              </main>
            </div>
         
        </Providers>
      </body>
    </html>
  );
}

So like this?
Avatar
Also providers
Avatar
Barbary LionOP
That's NextJS
But wait lemme test
Nope
doesn't change anything
Avatar
Can you provide a min repro repo? I'll check it when I'm free
Avatar
Barbary LionOP
A what? 😅
Avatar
Minimum Reproduction repository
Avatar
Barbary LionOP
oh
Avatar
Barbary LionOP
ye I can try
Avatar
I'll check it out when I'm free
Avatar
Barbary LionOP
Okay, I might want to go to sleep anyway lol
Avatar
Same
Avatar
Barbary LionOP
https://github.com/Tund101HD/minRepoLuciDev
This should be a working min repro repo. Added "FIXME" tags to the corresponding files that are of interest
Avatar
Barbary LionOP
TLDR for anyone else joining;

I am using app directory for my NextJS + i18n routing project. When I try and build it, it will show this error:
> Export encountered errors on following paths:
        /_error: /404
        /_error: /500
        /_not-found/page: /_not-found

This shouldn't happen, as it is defined:
This is my current tree:
├───app
│   └───[locale]
│       ├───[...rest]
        ├───not-found.tsx (will not be found)
        ├───error.tsx (will not be found)
        ├───providers.tsx //NextJS Provider
        ├───layout.tsx //Root layout
        └───page.tsx //Root page
├───config
├───i18n
└───styles



If I put the error.tsx into the pages directory, the missing paths for the error go away:
├───app
│   └───[locale]
│       ├───[...rest]
        ├───not-found.tsx (will not be found)
        ├───error.tsx (Does not matter if this is here or not)
        ├───providers.tsx //NextJS provider
        ├───layout.tsx //Root layout
        └───page.tsx //Root page
├───config
├───pages
    _error.tsx (This is being found and will resolve the error)
├───i18n
└───styles

After this change, the build error is reduced to
> Export encountered errors on following paths:
        /_not-found/page: /_not-found
If I now try and put the _not-found.tsx into the pages directory, to resolve it the same way as _error.tsx, I get a conflict error while building;
├───app
│   └───[locale]
│       ├───[...rest]
        ├───not-found.tsx (will not be found)
        ├───error.tsx (Does not matter if this is here or not)
        ├───providers.tsx //NextJS provider
        ├───layout.tsx //Root layout
        └───page.tsx //Root page
├───config
├───pages
    _error.tsx (This is being found and will resolve the error)
    _not-found.tsx (This will produce the conflict)
├───i18n
└───styles

 ⨯ Conflicting app and page file was found, please remove the conflicting files to continue:
 ⨯   "pages/_not-found.tsx" - "next/dist/client/components/not-found-error"

It does not matter, how the code in the not-found is shaped, I get either a conflict or it not being found all the time.
Now on to some important files;
app/[locale]/layout.tsx (The main layout file)
import "@/src/styles/globals.css";
import { Metadata, Viewport } from "next";
import { Link } from "@nextui-org/link";
import clsx from "clsx";

import { Providers } from "./providers";

import { siteConfig } from "@/src/config/site";
import { fontSans } from "@/src/config/fonts";
import { Navbar } from "@/src/components/navbar";


import { config } from '@fortawesome/fontawesome-svg-core'
import '@fortawesome/fontawesome-svg-core/styles.css'
import { getMessages } from "next-intl/server";
import { NextIntlClientProvider } from "next-intl";
config.autoAddCss = false

export const metadata: Metadata = {
  title: {
    default: siteConfig.name,
    template: `%s - ${siteConfig.name}`,
  },
  description: siteConfig.description,
  icons: {
    icon: "/favicon.ico",
  },
};

export const viewport: Viewport = {
  themeColor: [
    { media: "(prefers-color-scheme: light)", color: "white" },
    { media: "(prefers-color-scheme: dark)", color: "black" },
  ],
};

export default async function RootLayout({
  children,
  params: {locale}
}: {
  children: React.ReactNode;
  params: {locale: string}
}) {
  const messages = await getMessages();
  return (
    <html suppressHydrationWarning lang={locale}>
      <body
        className={clsx(
          "min-h-screen bg-background font-sans antialiased",
          fontSans.variable,
        )}
      >
        <Providers themeProps={{ attribute: "class", defaultTheme: "dark" }}>
          <NextIntlClientProvider messages={messages}>
            <div className="relative flex flex-col h-fit bg-main light:bg-light overflow-x-hidden scrollbar-hide">
              <Navbar />
              <main className="container mx-auto max-w-fit flex-grow h-fit z-0 scrollbar-hide">
                {children}
              </main>
            </div>
          </NextIntlClientProvider>
        </Providers>
      </body>
    </html>
  );
}
root/next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {}
const createNextIntlPlugin = require('next-intl/plugin');
const withNextIntl = createNextIntlPlugin();

const { webpack } = require("next/dist/compiled/webpack/webpack");
require('dotenv').config();
module.exports = withNextIntl({
  experimental: {
    missingSuspenseWithCSRBailout: false,
    turbo: {
      rules: {
        '*.svg': {
          loaders: ['@svgr/webpack', 'esbuild-loader'],
          as: '*.js',
        },
      },
    },
  },
  webpack: (config) => {
    config.plugins = config.plugins || [];
    config.plugins.push(
      new webpack.NormalModuleReplacementPlugin(/node:/, (resource) => {
        resource.request = resource.request.replace(/^node:/, "");
      }),
    );
    config.externals = {
      'next-intl': 'commonjs next-intl'
    }

    config.resolve.fallback = {
      ...config.resolve.fallback,async_hooks: false,
    }
    return config;
  },
});
Now normally I expect the error.tsx and the not-found.tsx in [locale] to be found. Putting them into the app/ directory will make them normal pages and I need to add a layout, after which they are not found still.

NextJS version: 14.2.5

What I might try when I wake up is;

Do I need getStaticProps in the error.tsx and not-found.tsx, in order them to be rendered as static pages?
Try to resolve the conflict somehow.

If anyone could point me in the right direction, that would be appreciated very much!
Avatar
Thanks, checking it out
Avatar
I have identified what the issue is.

So You'll need 2 not-found.tsx, one inside /app.

Since one is inside /app, a separate layout.tsx will be needed for that also
Avatar
Barbary LionOP
So can you send a layout of what to do?
Avatar
I'll create a PR
Avatar
@Barbary Lion So after this, I saw the issue was still there.

The issue is with webpack config. If I comment it, build is running fine
Avatar
-# app/not-found.tsx
'use client';
 
import Error from 'next/error';
import { redirect } from 'next/navigation';
 
export default function NotFound() {
  // redirect('/'); // Add this(if needed) after commenting use client and the return statement
  return ( 
    <html lang="en">
      <body>
        <Error statusCode={404} />
      </body>
    </html>
  );
}


-# app/layout.tsx
import React from "react";


export default async function RootLayout({ children } : { children: React.ReactNode}) {
    return (
        <>
        {children}
        </>
    )
}


Copy same error.tsx in app/ folder from app/[locale]

app/[locale]/not-found.tsx remains same

Comment WebPack config(to be fixed)
Answer
Avatar
Barbary LionOP
Okay
What exactly do you mean by "comment WebPack config"?
Nevermind I think I know what you mean, just tested it
Let me test on the full site to see if commenting webpack config is breaking
Avatar
Barbary LionOP
Solution builds on Vercel as well as on my machine, so change is not breaking. Thanks @Anay-208 for your help and time, really appreciate it!
Marking the above answer as solution, the webpack config was an old fix and I suspect the fallback to have been the problem.