You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS 14 App Router动态路由返回404页却带200状态码,如何保留loading.tsx并修正?

Next.js 14 App Router:保留loading.tsx同时正确返回404状态码

问题原因

当路由组件被loading.tsx(即Suspense边界)包裹时,若在页面组件的顶层逻辑中调用notFound(),服务器端已经完成初始响应的状态码设置(默认200),后续的notFound()只能触发客户端导航到404页面,无法修改服务器返回的状态码。

解决方案

将notFound()的调用时机提前到数据获取阶段,让Next.js在服务器端处理数据请求时就能识别404状态,同时保留loading.tsx的加载状态提示。

步骤1:修改数据获取函数

移除getAgentBySlug中返回null的逻辑,在捕获到agent不存在的错误时直接调用notFound():

import { notFound } from 'next/navigation';

const getAgentBySlug = async ({ slug }: RequestParameters) => {
  try {
    return await Fetch<RequestResponses, RequestParameters>({
      url: `agent/getAgentBySlug/${slug}`,
      next: {
        tags: [BASE_AGENT],
      },
    });
  } catch (error) {
    // 确认此错误是agent不存在导致的(可根据API返回的错误信息判断)
    notFound();
    // 添加类型断言,避免TS报错
    throw new Error('Agent not found');
  }
};

步骤2:简化页面组件逻辑

页面组件无需再判断agent是否为null,直接使用获取到的数据即可:

export default async function AgentPage({ params: { slug } }: AgentPageProps) {
  const agent = await getAgentBySlug({ slug });

  return (
    // 页面渲染内容
  );
}

补充:若API返回404但未抛出错误

如果你的Fetch工具函数不会在响应状态为404时自动抛出错误,需要手动检查响应状态并触发notFound():

// 假设Fetch函数返回原始响应对象,需自行解析
const getAgentBySlug = async ({ slug }: RequestParameters) => {
  const response = await fetch(`/api/agent/getAgentBySlug/${slug}`, {
    next: { tags: [BASE_AGENT] }
  });

  if (!response.ok) {
    if (response.status === 404) {
      notFound();
    }
    // 处理其他错误
    throw new Error('Failed to fetch agent');
  }

  return await response.json();
};

这样调整后,当agent不存在时,数据获取阶段会立即触发notFound(),Next.js服务器会正确返回404状态码,同时loading.tsx会正常显示直到数据请求完成(或错误触发),兼顾了用户体验和状态码正确性。

内容的提问来源于stack exchange,提问作者AmirManshadi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 03:02:25