当Next.js中传递了一个动态路由的无效参数时,如何返回404 Not Found页面和HTTP状态



例如,我有一个动态路由/blog/[article-id]

当访问现有的博客文章/blog/id-that-exist时,它按预期工作,现在我想正确处理/blog/id-that-does-not-exist的情况。

/blog/[id].jsx中的代码看起来像:

export const getStaticPaths async () => {
return {
fallback: true,
paths: (await sequelize.models.Article.findAll()).map(
article => {
return {
params: {
pid: article.slug,
}
}
}
),
}
}
export const getStaticProps async () => {
// Try to get it from the database. Returns none if does not exist.
const article = await sequelize.models.Article.findOne({
where: { slug: pid },
});
return { props: { article: article } };
}
const ArticlePage = (props) => {
// This can happen due to fallback: true while waiting for
// a page that was not rendered at build time to build.
const router = useRouter()
if (router.isFallback) {
return <div>loading</div>;
}
return (
<div>{props.article.body}</div>
);
};
export const getStaticPaths = getStaticPathsArticle;
export const getStaticProps = getStaticPropsArticle;
export default ArticlePage;

我看到了一个相关的问题:如何处理调用API的Next.js中的动态路由找不到404?但我不确定它是否与我在这里所问的相同,因为这不依赖于使用任何外部API。

Next.js 10的notFound: true

从Next.js 10开始,我们可以做:

export const getStaticProps async () => {
// Try to get it from the database. Returns none if does not exist.
const article = await sequelize.models.Article.findOne({
where: { slug: pid },
});
if (!article) {
return {
notFound: true
}
}
return { props: { article: article } };
}

如文件所示:https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-静态生成

当返回notFound时,渲染函数ArticlePage永远不会被调用,而是返回默认的404页面。

但请注意,ArticlePage确实获得了

出于开发模式中的某些原因:

  • 我没有得到预期的404 HTTP状态代码
  • ArticlePage,所以如果您忘记处理回退情况,它可能会由于缺少属性而崩溃

这让我有点困惑。但在生产模式下,一切都如预期。

Next.js 10之前的解决方案

如图所示https://github.com/vercel/next.js/discussions/10960#discussioncomment-1201你以前可以做这样的事情:

const ArticlePage = (props) => {
if (!props.article) {
return <>
<Head>
<meta name="robots" content="noindex">
</Head>
<DefaultErrorPage statusCode={404} />
</>
}
return (
<div>{props.article.body}</div>
);
};

但这并不理想,因为我相信它没有正确设置HTTP返回代码,而且我不知道如何做到这一点

在Next.js 10.2.2上测试。

我已经阅读了您对Next.js v.10之后的解决方案的回答,但我不知道在开发过程中显示预期的http 404代码有什么问题。

我使用Next.JS v.12,在开发时正常得到预期的404

import { GetStaticPaths, GetStaticProps } from 'next'
import { useRouter } from 'next/router'
import { ParsedUrlQuery } from 'querystring'
import Loading from '../../components/loading'
export const getStaticPaths: GetStaticPaths = async () => {
//your paths
return { paths, fallback: true }
}
export const getStaticProps: GetStaticProps = async ({ params }: { params?: ParsedUrlQuery }) => {
//get your props
if (!target){
return {notFound: true}
}
return { props: { ... }, revalidate: 86400}
}
function Index({ ... }) {
const router = useRouter()

if (router.isFallback) {
return <Loading />
}
return (
<div>
//my content
</div>
)
}
export default Index

当找不到目标时,如果我创建了一个或仅创建了默认的404页面,它会在pages/404.tsx中呈现我的自定义404组件。

这应该在开发和生产过程中正常工作。

最新更新