not-found.js
Source URL: https://nextjs.org/docs/app/api-reference/file-conventions/not-found
not-found.js
Section titled “not-found.js”Next.js provides two conventions to handle not found cases:
not-found.js: Used when you call thenotFoundfunction in a route segment.global-not-found.js: Used to define a global 404 page for unmatched routes across your entire app. This is handled at the routing level and doesn’t depend on rendering a layout or page.
not-found.js
Section titled “not-found.js”The not-found file is used to render UI when the notFound function is thrown within a route segment. Along with serving a custom UI, Next.js will return a 200 HTTP status code for streamed responses, and 404 for non-streamed responses.
import Link from 'next/link'
export default function NotFound() { return ( <div> <h2>Not Found</h2> <p>Could not find requested resource</p> <Link href="/">Return Home</Link> </div> )}import Link from 'next/link'
export default function NotFound() { return ( <div> <h2>Not Found</h2> <p>Could not find requested resource</p> <Link href="/">Return Home</Link> </div> )}global-not-found.js (experimental)
Section titled “global-not-found.js (experimental)”The global-not-found.js file lets you define a 404 page for your entire application. Unlike not-found.js, which works at the route level, this is used when a requested URL doesn’t match any route at all. Next.js skips rendering and directly returns this global page.
The global-not-found.js file bypasses your app’s normal rendering, which means you’ll need to import any global styles, fonts, or other dependencies that your 404 page requires.
Good to know: A smaller version of your global styles, and a simpler font family could improve performance of this page.
global-not-found.js is useful when you can’t build a 404 page using a combination of layout.js and not-found.js. This can happen in two cases:
- Your app has multiple root layouts (e.g.
app/(admin)/layout.tsxandapp/(shop)/layout.tsx), so there’s no single layout to compose a global 404 from. - Your root layout is defined using top-level dynamic segments (e.g.
app/[country]/layout.tsx), which makes composing a consistent 404 page harder.
To enable it, add the globalNotFound flag in next.config.ts:
import type { NextConfig } from 'next'
const nextConfig: NextConfig = { experimental: { globalNotFound: true, },}
export default nextConfigThen, create a file in the root of the app directory: app/global-not-found.js:
// Import global styles and fontsimport './globals.css'import { Inter } from 'next/font/google'import type { Metadata } from 'next'
const inter = Inter({ subsets: ['latin'] })
export const metadata: Metadata = { title: '404 - Page Not Found', description: 'The page you are looking for does not exist.',}
export default function GlobalNotFound() { return ( <html lang="en" className={inter.className}> <body> <h1>404 - Page Not Found</h1> <p>This page does not exist.</p> </body> </html> )}// Import global styles and fontsimport './globals.css'import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'] })
export const metadata = { title: '404 - Page Not Found', description: 'The page you are looking for does not exist.',}
export default function GlobalNotFound() { return ( <html lang="en" className={inter.className}> <body> <h1>404 - Page Not Found</h1> <p>This page does not exist.</p> </body> </html> )}Unlike not-found.js, this file must return a full HTML document, including <html> and <body> tags.
Reference
Section titled “Reference”not-found.js or global-not-found.js components do not accept any props.
Good to know: In addition to catching expected
notFound()errors, the rootapp/not-found.jsandapp/global-not-found.jsfiles handle any unmatched URLs for your whole application. This means users that visit a URL that is not handled by your app will be shown the exported UI.
Examples
Section titled “Examples”Data Fetching
Section titled “Data Fetching”By default, not-found is a Server Component. You can mark it as async to fetch and display data:
import Link from 'next/link'import { headers } from 'next/headers'
export default async function NotFound() { const headersList = await headers() const domain = headersList.get('host') const data = await getSiteData(domain) return ( <div> <h2>Not Found: {data.name}</h2> <p>Could not find requested resource</p> <p> View <Link href="/blog">all posts</Link> </p> </div> )}import Link from 'next/link'import { headers } from 'next/headers'
export default async function NotFound() { const headersList = await headers() const domain = headersList.get('host') const data = await getSiteData(domain) return ( <div> <h2>Not Found: {data.name}</h2> <p>Could not find requested resource</p> <p> View <Link href="/blog">all posts</Link> </p> </div> )}If you need to use Client Component hooks like usePathname to display content based on the path, you must fetch data on the client-side instead.
Metadata
Section titled “Metadata”For global-not-found.js, you can export a metadata object or a generateMetadata function to customize the <title>, <meta>, and other head tags for your 404 page:
Good to know: Next.js automatically injects
<meta name="robots" content="noindex" />for pages that return a 404 status code, includingglobal-not-found.jspages.
import type { Metadata } from 'next'
export const metadata: Metadata = { title: 'Not Found', description: 'The page you are looking for does not exist.',}
export default function GlobalNotFound() { return ( <html lang="en"> <body> <div> <h1>Not Found</h1> <p>The page you are looking for does not exist.</p> </div> </body> </html> )}export const metadata = { title: 'Not Found', description: 'The page you are looking for does not exist.',}
export default function GlobalNotFound() { return ( <html lang="en"> <body> <div> <h1>Not Found</h1> <p>The page you are looking for does not exist.</p> </div> </body> </html> )}Version History
Section titled “Version History”| Version | Changes |
|---|---|
v15.4.0 | global-not-found.js introduced (experimental). |
v13.3.0 | Root app/not-found handles global unmatched URLs. |
v13.0.0 | not-found introduced. |