Next.js 13+Strapi v4动态路由:无效Slug返回空数据而非404求助
Next.js 13 App Router + Strapi v4动态路由404问题解决办法
问题根因
访问不存在的slug时,Strapi API返回的是200成功响应,但data字段是空数组,并非HTTP错误。你当前的代码仅处理了请求失败和加载状态,未判断数据为空的情况,因此页面会显示空内容而非404页面。
解决办法
方法1:客户端组件内手动处理空数据
既然使用了客户端组件(带有'use client'标识),直接在获取数据后检查data.data的长度,为空时渲染404内容即可:
'use client' import useSWR from 'swr'; import axios from 'axios'; const fetcher = (url) => axios.get(url).then(res => res.data); export default function SingleWork({ params }) { const { slug } = params; const { data, error } = useSWR( `http://localhost:1337/api/works?filters[slug][$eq]=${slug}&populate=*`, fetcher ); if (error) return <div>加载数据出错...</div>; if (!data) return <div>加载中...</div>; // 新增:数据为空时显示404内容 if (data.data.length === 0) { return ( <div> <h1>404</h1> <p>该作品不存在</p> </div> ); } const work = data.data[0]; return ( <div> <h1>{work.attributes.title}</h1> <p>{work.attributes.description}</p> </div> ) }
方法2:改用服务器组件(更推荐)
Next.js 13 App Router中,服务器组件更适合处理数据获取逻辑,还能直接调用官方的notFound()函数触发系统默认404页面,体验更统一:
将app/works/[slug]/page.js修改为服务器组件(移除'use client'标识):
import axios from 'axios'; import { notFound } from 'next/navigation'; export default async function SingleWork({ params }) { const { slug } = params; let data; try { const res = await axios.get( `http://localhost:1337/api/works?filters[slug][$eq]=${slug}&populate=*` ); data = res.data; } catch (err) { return <div>加载数据出错...</div>; } // 数据为空时触发404 if (data.data.length === 0) { notFound(); } const work = data.data[0]; return ( <div> <h1>{work.attributes.title}</h1> <p>{work.attributes.description}</p> </div> ) }
额外优化:使用Strapi单条数据查询接口
你当前是查询所有符合slug的作品,其实可以直接调用Strapi的findOne接口获取单条数据——当slug不存在时,Strapi会直接返回404错误,无需手动判断数组长度,效率更高:
请求URL修改为:
`http://localhost:1337/api/works/${slug}?populate=*`
(前提:Strapi中work内容类型的slug字段已设置为唯一,且开启了findOne接口的访问权限)
对应的服务器组件代码:
import axios from 'axios'; import { notFound } from 'next/navigation'; export default async function SingleWork({ params }) { const { slug } = params; let work; try { const res = await axios.get( `http://localhost:1337/api/works/${slug}?populate=*` ); work = res.data.data; } catch (err) { // 捕获404错误,触发系统默认404页面 if (err.response?.status === 404) { notFound(); } return <div>加载数据出错...</div>; } return ( <div> <h1>{work.attributes.title}</h1> <p>{work.attributes.description}</p> </div> ) }
内容的提问来源于stack exchange,提问作者rnrh
相关产品推荐
相关产品推荐

