Skip to content

not-found.js

Next.js 提供了两种处理未找到情况的约定:

¥Next.js provides two conventions to handle not found cases:

  • not-found.js:在路由段中调用 notFound 函数时使用。

    ¥not-found.js: Used when you call the notFound function in a route segment.

  • global-not-found.js:用于为整个应用中不匹配的路由定义全局 404 页面。此功能在路由级别处理,不依赖于布局或页面渲染。

    ¥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

notFound 函数在路由段内抛出时,未找到的文件用于渲染 UI。除了提供自定义 UI 之外,Next.js 还将针对流式响应返回 200 HTTP 状态代码,针对非流式响应返回 404

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

tsx
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(实验性)

¥global-not-found.js (experimental)

global-not-found.js 文件允许你为整个应用定义 404 页面。与在路由级别工作的 not-found.js 不同,此功能用于请求的 URL 完全不匹配任何路由的情况。Next.js 跳过渲染并直接返回此全局页面。

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

当你无法使用 layout.jsnot-found.js 的组合构建 404 页面时,此功能非常有用。这可能发生在两种情况下:

¥This 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:

  • 你的应用有多个根布局(例如 app/(admin)/layout.tsxapp/(shop)/layout.tsx),因此没有单一的布局可以组成全局 404 页面。

    ¥Your app has multiple root layouts (e.g. app/(admin)/layout.tsx and app/(shop)/layout.tsx), so there's no single layout to compose a global 404 from.

  • 你的根布局是使用顶层动态段(例如 app/[country]/layout.tsx)定义的,这使得编写一致的 404 页面变得更加困难。

    ¥Your root layout is defined using top-level dynamic segments (e.g. app/[country]/layout.tsx), which makes composing a consistent 404 page harder.

要启用此功能,请在 next.config.ts 中添加 globalNotFound 标志:

¥To enable it, add the globalNotFound flag in next.config.ts:

tsx
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    globalNotFound: true,
  },
}

export default nextConfig

然后,在 app 目录的根目录中创建一个文件:app/global-not-found.js

¥Then, create a file in the root of the app directory: app/global-not-found.js:

tsx
export default function GlobalNotFound() {
  return (
    <html>
      <body>
        <h1>404 - Page Not Found</h1>
        <p>This page does not exist.</p>
      </body>
    </html>
  )
}

not-found.js 不同,此文件必须返回完整的 HTML 文档,包括 <html><body> 标签。

¥Unlike not-found.js, this file must return a full HTML document, including <html> and <body> tags.

参考

¥Reference

属性

¥Props

not-found.jsglobal-not-found.js 组件不接受任何 props。

¥not-found.js or global-not-found.js components do not accept any props.

需要了解:除了捕获预期的 notFound() 错误外,根 app/not-found.jsapp/global-not-found.js 文件还会处理整个应用的任何不匹配的 URL。这意味着,如果用户访问的 URL 未经你的应用处理,则将显示导出的 UI。

¥Good to know: In addition to catching expected notFound() errors, the root app/not-found.js and app/global-not-found.js files 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

数据获取

¥Data Fetching

默认情况下,not-found 是服务器组件。你可以将其标记为 async 以获取并显示数据:

¥By default, not-found is a Server Component. You can mark it as async to fetch and display data:

tsx
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>
  )
}

如果你需要使用像 usePathname 这样的客户端组件钩子来根据路径显示内容,则必须改为在客户端获取数据。

¥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

对于 global-not-found.js,你可以导出 metadata 对象或 generateMetadata 函数来自定义 404 页面的 <title><meta> 和其他 head 标签:

¥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:

tsx
export const metadata = {
  title: 'Not Found',
  description: 'The page you are looking for does not exist.',
}

export default function GlobalNotFound() {
  return (
    <div>
      <h1>Not Found</h1>
      <p>The page you are looking for does not exist.</p>
    </div>
  )
}

版本历史

¥Version History

版本更改
v15.4.0global-not-found.js 引入(实验性)。
v13.3.0app/not-found 处理全局不匹配的 URL。
v13.0.0not-found 已引入。