Dav*_*vid 6 reactjs contentful next.js
我的 ISR 有一点问题。我的 revalidate 属性等于 1s,如下所示
export async function getStaticProps({ params }) {
const data = await client.getEntries({
content_type: "product",
"fields.name": params.slug,
});
if (!data.items[0]) {
return {
notFound: true,
};
}
return {
props: {
article: data.items[0],
revalidate: 1,
},
};
}
Run Code Online (Sandbox Code Playgroud)
当我在 Contentful 中创建产品时,页面会按我的预期创建。当我想进入不存在的页面时,我会收到预期的 404 错误。当我更改现有产品中 Contentful 中的某些内容或将其删除时,问题就会出现。
当我在 Contentful 中删除产品时,产品页面中的产品列表会更新并且产品会消失,但我仍然可以进入该产品的页面。此外,当我重命名产品名称时,产品列表也会更新,但我仍然可以访问较早的页面名称。
有什么办法可以解决这个问题吗?
获取静态路径
export async function getStaticPaths() {
const data = await client.getEntries({
content_type: "product",
});
return {
paths: data.items.map((item) => ({
params: { slug: item.fields.name },
})),
fallback: true,
};
}
Run Code Online (Sandbox Code Playgroud)
产品页面
const Article = ({ article }) => {
const router = useRouter();
if (router.isFallback) return <p>Loading...</p>;
return (
<div>
<h1>Hello! {article.fields.name}</h1>
<Link href="/about">
<a>Back to about!</a>
</Link>
</div>
);
};
Run Code Online (Sandbox Code Playgroud)
编辑
当我在 Contentful 中将产品名称从“product77”更改为“product7”时,重新验证我的产品77版本中的静态页面仍然存在,并且我仍然可以进入该页面。

重新验证后不是应该删除吗?
已删除的页面无法删除,但会出现 404 错误。一个人必须使用
下面的示例使用条目 id 来构建路径,例如example.com/post/90803230238。对于非 ID 路径,例如使用自定义字段example.com/post/how-to-make-icecream,请阅读本答案末尾的注释。
这样做的先决条件是 getStaticPaths和getStaticProps进行相应的配置。
// /pages/blog/[...post].jsx
function Post({ postData }) {
return (
// ...
);
}
// Only runs once during build
export async function getStaticPaths() {
const res = await fetch("https://.../posts");
const posts = await res.json();
// Prerender paths during build
const paths = posts.map((post) => ({
params: { post: post.id },
}));
return {
paths,
fallback: "blocking" // must be "blocking"
};
}
// Runs during build and every revalidation
export async function getStaticProps(context) {
const res = await fetch(`https://.../posts/${context.params.post}`);
const postData = await res.json();
// Check if the page exists in the CMS using the API response
if(!postData){
// The page doesn't exist in the CMS, return notFound to trigger a 404
return{
notFound: true,
// Pick one of the following
revalidate: 30, // <- ISR, interval in seconds between revalidations
revalidate: false // On-demand
}
}
// Return page props
return {
props: {
postData,
},
// Pick one of the following
revalidate: 30, // <- ISR, interval in seconds between revalidations
revalidate: false // On-demand
};
}
Run Code Online (Sandbox Code Playgroud)
上述代码的主要要点是:
getStaticPaths仅在初始构建期间运行的路径getStaticPaths必须用作"blocking"值fallbackgetStaticProps它在初始构建和每次重新验证期间运行,每次都应该通过 API 请求询问页面状态(已发布、未发布,...) - 如果页面处于活动状态,则返回页面属性 - 如果页面处于非活动/已删除状态, 返回 a notFound:true, 回退到./pages/404.jsx页面按需重新验证需要一个额外的文件,即 Webhook 可以向其发送通知的 API 端点。
// /pages/blog/[...post].jsx
function Post({ postData }) {
return (
// ...
);
}
// Only runs once during build
export async function getStaticPaths() {
const res = await fetch("https://.../posts");
const posts = await res.json();
// Prerender paths during build
const paths = posts.map((post) => ({
params: { post: post.id },
}));
return {
paths,
fallback: "blocking" // must be "blocking"
};
}
// Runs during build and every revalidation
export async function getStaticProps(context) {
const res = await fetch(`https://.../posts/${context.params.post}`);
const postData = await res.json();
// Check if the page exists in the CMS using the API response
if(!postData){
// The page doesn't exist in the CMS, return notFound to trigger a 404
return{
notFound: true,
// Pick one of the following
revalidate: 30, // <- ISR, interval in seconds between revalidations
revalidate: false // On-demand
}
}
// Return page props
return {
props: {
postData,
},
// Pick one of the following
revalidate: 30, // <- ISR, interval in seconds between revalidations
revalidate: false // On-demand
};
}
Run Code Online (Sandbox Code Playgroud)
使用res.revalidate(``/${reqBody.path}``)来自 的逻辑调用页面的新评估getStaticProps。
现在,如果有人删除 CMS 中的页面,并为已删除的页面路径触发上述重新验证 Webhook 处理程序,则该路径将提供 404 页面而不是原始页面。
但是,页面本身不会从磁盘中删除。
使用路径的非 ID 自定义字段值重新验证
在 Contentful 中,在“取消发布”Webhook 通知期间,type: "DeletedEntry"Webhook 响应正文中仅存在未发布的条目 ID 和 a。所有其他字段值(例如path触发重新验证所需的值)均不可用。在这里,我们必须发出额外的请求来获取非活动者的帖子字段值。
Contentful 提供了Content Preview API,它允许您甚至从非活动条目中获取数据。
以下是使用 ID 以外的自定义路径值时 Webhook API 端点的伪代码:
// /pages/api/revalidate-post.js
export async function handler(req, res) {
try {
const reqBody = JSON.parse(req.body);
await res.revalidate(`/post/${reqBody.sys.id}`); // revalidate post using entry id
return res.json({ revalidated: true });
} catch (err) {
return res.status(500).send("Error revalidating");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3703 次 |
| 最近记录: |