如何在Next.js 13 App Router中显示自定义410页面
在Next.js 13 App Router中实现自定义410页面
Next.js 13 App Router没有像处理404那样内置notFound()函数直接触发410页面,需要手动实现,以下是具体方案:
1. 创建自定义410页面组件
在app目录下新建410/page.js(或自定义路径如app/gone/page.js),编写页面UI并设置410状态码:
export default function GonePage() { return ( <div style={{ padding: '2rem', textAlign: 'center' }}> <h1>410 - 资源已永久移除</h1> <p>您访问的资源已被永久删除,不会再恢复。</p> </div> ); } // 设置页面状态码为410 export async function generateMetadata() { return { status: 410, }; }
2. 在业务路由中触发410
如果某个路由对应的资源已永久删除,在Server Component中判断后直接渲染410组件,并同步设置状态码:
比如在app/blog/[slug]/page.js中:
import GonePage from '@/app/410/page'; // 模拟获取文章数据的函数 async function fetchBlogPost(slug) { // 实际业务逻辑:从数据库/API获取数据 const res = await fetch(`https://your-api.com/posts/${slug}`); if (!res.ok) { // 假设410状态码表示资源永久移除 if (res.status === 410) { return { isPermanentlyRemoved: true }; } return null; } return res.json(); } export default async function BlogPostPage({ params }) { const post = await fetchBlogPost(params.slug); // 判断资源是否永久移除 if (post?.isPermanentlyRemoved) { return <GonePage />; } // 资源存在时正常渲染 return ( <div> <h1>{post.title}</h1> <div>{post.content}</div> </div> ); } // 同步设置元数据中的状态码 export async function generateMetadata({ params }) { const post = await fetchBlogPost(params.slug); if (post?.isPermanentlyRemoved) { return { status: 410 }; } return { title: post?.title || '博客文章', }; }
3. 用Middleware批量拦截旧路由
如果有一批已永久移除的旧路由,可以通过middleware.js统一拦截并返回410页面:
import { NextResponse } from 'next/server'; export function middleware(request) { // 匹配所有需要返回410的旧路由 const removedPaths = ['/blog/old-post-1', '/blog/old-post-2', '/archive/2022']; if (removedPaths.includes(request.nextUrl.pathname)) { // 重写到自定义410页面,并设置410状态码 const response = NextResponse.rewrite(new URL('/410', request.url)); response.headers.set('status', '410 Gone'); return response; } } // 指定Middleware生效的路由范围 export const config = { matcher: ['/blog/:path*', '/archive/:path*'], };
注意事项
- 确保
generateMetadata中的状态码设置与页面组件的判断逻辑一致,避免状态码与页面内容不匹配。 - 如果是静态生成的路由,需要在构建时就确定资源是否永久移除,或使用增量静态再生(ISR)更新状态。
内容的提问来源于stack exchange,提问作者amirhossein
相关产品推荐
相关产品推荐

