主题
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 thenotFoundfunction 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.
global-not-found.js 文件会绕过应用的正常渲染,这意味着你需要导入 404 页面所需的所有全局样式、字体或其他依赖。
¥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.
当你无法使用 layout.js 和 not-found.js 的组合构建 404 页面时,global-not-found.js 非常有用。这可能发生在两种情况下:
¥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:
你的应用有多个根布局(例如
app/(admin)/layout.tsx和app/(shop)/layout.tsx),因此没有单一的布局可以组成全局 404 页面。¥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.你的根布局是使用顶层动态段(例如
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
// Import global styles and fonts
import './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>
)
}与 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.js 或 global-not-found.js 组件不接受任何 props。
¥not-found.js or global-not-found.js components do not accept any props.
需要了解:除了捕获预期的
notFound()错误外,根app/not-found.js和app/global-not-found.js文件还会处理整个应用的任何不匹配的 URL。这意味着,如果用户访问的 URL 未经你的应用处理,则将显示导出的 UI。¥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
数据获取
¥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:
需要了解:Next.js 会自动为返回 404 状态码的页面(包括
global-not-found.js页面)注入<meta name="robots" content="noindex" />。¥Good to know: Next.js automatically injects
<meta name="robots" content="noindex" />for pages that return a 404 status code, includingglobal-not-found.jspages.
tsx
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>
)
}版本历史
¥Version History
| 版本 | 更改 |
|---|---|
v15.4.0 | global-not-found.js 引入(实验性)。 |
v13.3.0 | 根 app/not-found 处理全局不匹配的 URL。 |
v13.0.0 | not-found 已引入。 |