NextJS 13.4.7动态路由中notFound()无法返回404状态码求助
问题
基于NextJS 13.4.7(App Router)搭建Contentful无头CMS应用,采用动态路由。当CMS中无对应slug的页面数据时,调用notFound()能触发自定义notfound.tsx页面,但服务器未返回404状态码,影响SEO,需解决如何让notFound()返回404状态码。
相关代码如下:
/app/[...slug]/page.tsx
export default async function ContentPageRoute({ params }) { const pathname = `/${params.slug.join("/")}`; const { pageCollection } = await getPageBySlug({ slug: pathname, }); const page = pageCollection?.items[0]; if (!isDefined(page)) notFound(); return ( <Suspense fallback="Loading"> <ContentPage breadcrumbs={ <Breadcrumbs style="containerWithSpaceBottom" pathname={pathname} /> } page={page} /> </Suspense> ); }
/app/notfound.tsx
export default function NotFound() { return ( <p className="mt-5 mb-3 container-padding text-center"> 很抱歉,未找到该页面 </p> ); }
请求结果说明:服务器返回200状态码,而非预期的404状态码。
解决方法
1. 确认notFound()在服务器组件中调用
notFound()仅在服务器组件中生效,确保page.tsx没有添加'use client'指令(async/await组件默认是服务器组件)。若误加客户端指令,notFound()无法正确触发404状态码。
2. 验证数据判断逻辑的正确性
检查isDefined函数实现,确保它能正确识别page为undefined的情况,示例正确实现:
function isDefined<T>(val: T | undefined | null): val is T { return val !== undefined && val !== null; }
同时确认getPageBySlug在无对应数据时,返回的pageCollection.items为空数组,导致page为undefined。
3. 显式触发404响应(替代方案)
若notFound()仍未返回404状态码,可直接使用NextResponse.notFound()返回404响应,同时保留自定义notfound.tsx页面:
修改page.tsx:
import { NextResponse } from 'next/server'; export default async function ContentPageRoute({ params }) { const pathname = `/${params.slug.join("/")}`; const { pageCollection } = await getPageBySlug({ slug: pathname, }); const page = pageCollection?.items[0]; if (!isDefined(page)) { return NextResponse.notFound(); } return ( <Suspense fallback="Loading"> <ContentPage breadcrumbs={ <Breadcrumbs style="containerWithSpaceBottom" pathname={pathname} /> } page={page} /> </Suspense> ); }
该方法会直接返回404状态码,Next.js会自动渲染自定义notfound.tsx页面。
4. 检查环境与缓存
- 开发环境下可能存在缓存问题,尝试重启开发服务器或清除浏览器缓存后测试。
- 生产环境部署后,确保Next.js的静态生成或服务器渲染逻辑正常,避免缓存旧的响应状态。
内容的提问来源于stack exchange,提问作者Ivo Brands
相关产品推荐
相关产品推荐

