Next.js 提供了两种处理未找到情况的约定:
not-found.js: 当你在路由段中调用 notFound 函数时使用。global-not-found.js: 用于为整个应用中不匹配的路由定义一个全局 404 页面。这在路由层面处理,不依赖于渲染布局或页面。not-found.jsnot-found 文件用于在路由段内抛出 notFound 函数时渲染 UI。除了提供自定义 UI,Next.js 会为流式响应返回 200 HTTP 状态码,为非流式响应返回 404。
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)global-not-found.js 文件允许你为整个应用程序定义一个 404 页面。与在路由层面工作的 not-found.js 不同,当请求的 URL 完全不匹配任何路由时,会使用此文件。Next.js 会跳过渲染,直接返回这个全局页面。
global-not-found.js 文件会绕过你的应用正常渲染,这意味着你需要导入你的 404 页面所需的任何全局样式、字体或其他依赖项。
须知:较小版本的全局样式和更简单的字体族可以提高此页面的性能。
global-not-found.js 在你无法通过 layout.js 和 not-found.js 组合来构建 404 页面时很有用。这可能发生在两种情况下:
app/(admin)/layout.tsx 和 app/(shop)/layout.tsx),因此没有单一布局可以组合出全局 404 页面。app/[country]/layout.tsx),这使得构建一致的 404 页面更加困难。要启用它,请在 next.config.ts 中添加 globalNotFound 标志:
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
experimental: {
globalNotFound: true,
},
};
export default nextConfig;然后,在 app 目录的根部创建一个文件:app/global-not-found.js:
// 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>
);
}// Import global styles and fonts
import "./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>
);
}与 not-found.js 不同,此文件必须返回一个完整的 HTML 文档,包括 <html> 和 <body> 标签。
not-found.js 或 global-not-found.js 组件不接受任何属性(props)。
须知:除了捕获预期的
notFound()错误,根部的app/not-found.js和app/global-not-found.js文件还会处理整个应用中任何不匹配的 URL。这意味着访问未被你的应用处理的 URL 的用户将看到导出的 UI。
默认情况下,not-found 是一个服务器组件。你可以将其标记为 async 以获取并显示数据:
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>
);
}如果你需要使用像 usePathname 这样的客户端组件 Hook 来根据路径显示内容,你必须改为在客户端获取数据。
对于 global-not-found.js,你可以导出一个 metadata 对象或一个 generateMetadata 函数,以自定义 404 页面的 <title>、<meta> 和其他头部标签:
须知:Next.js 会自动为返回 404 状态码的页面(包括
global-not-found.js页面)注入<meta name="robots" content="noindex" />。
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>
);
}| 版本 | 变更 |
|---|---|
v15.4.0 | 引入 global-not-found.js(实验性)。 |
v13.3.0 | 根部的 app/not-found 处理全局不匹配的 URL。 |
v13.0.0 | 引入 not-found。 |