typescript - 如何清除 NextJs GetStaticPaths 缓存/“取消发布”动态路由?
问题描述
我认为这是一个很普通的问题,但我在谷歌上找不到任何东西。
我正在学习 NextJs(使用 TypeScript),并且我有一个站点成功地使用动态路由、SSR 和增量再生,所有设置和部署到 Vercel。这是我的动态路由处理程序中的GetStaticProps
and代码示例:GetStaticPaths
export const getStaticPaths: GetStaticPaths = async () => {
const routes = new CmsHelper().GetRoutes();
const paths = (await routes).items.map((item, index, items) => {
return item.fields.urlPath;
})
return {
paths: paths,
fallback: 'blocking',
};
}
export const getStaticProps: GetStaticProps = async (context) => {
const urlParts = context.params?.url as string[] || [];
const urlPath = `/${urlParts.join('/')}`;
const article = await new CmsHelper().GetArticle(urlPath);
return {
props: {
article
},
revalidate: 10,
}
}
如果我在构建时间后请求在 cms 中发布的新路径,它会成功在服务器上重新生成并返回页面。
到目前为止,一切都很好。
但是,如果我在我的 CMS 中取消发布路由......它仍然由应用程序返回,除非我重建和重新部署(或以其他方式导致进程在开发中重新启动)。
所以我的问题是:如何动态地使 NextJs 从其 GetStaticPaths 缓存中删除动态路由?
我知道GetStaticProps
由于配置原因,最多每 10 秒调用一次revalidate
。但据我所知,GetStaticPaths
只有当请求来自当前未缓存的路由时才会调用(?)
换句话说,对于与无头 CMS 的集成,如何在不触发重建/部署的情况下支持使用 NextJs 取消发布或重命名页面?
提前致谢!
解决方案
也许试试这里描述的这种方法。
还在这里提供代码以供参考。
// pages/blog/[slug].js
import {useRouter} from 'next/router'
import DefaultErrorPage from 'next/error'
export async function getStaticProps({ params }) {
// fetch data from CMS through params
const post = await getBlogItem(params.slug)
return {
props: {
post
}
}
}
export async function getStaticPaths() {
return {
fallback: true,
paths: []
}
}
export default function MyPage({post}) {
const router = useRouter()
if(router.isFallback) {
return <h1>Loading...</h1>
}
// This includes setting the noindex header because static files always return a status 200 but the rendered not found page page should obviously not be indexed
if(!post) {
return <>
<Head>
<meta name="robots" content="noindex">
</Head>
<DefaultErrorPage statusCode={404} />
</>
}
return <h1>{post.title}</h1>
}
因此,与其删除/清除缓存,不如尝试成功处理您正在获取的内容是“未发布”的,如果是这样,您可以显示一个404 Not found
页面或您选择的内容。
像这样的东西:
export async function getStaticProps(context) {
const {params: {id}} = context
let data;
try {
data = await httpClient...
} catch (err) {
if (not err is caused due to content being unpublished){
// re throw it
throw err;
}
// Else handle it gracefully
data = null;
}
return {
props: {
data,
},
revalidate: 1
};
}
然后在您的视图上:
export default function Data(props) {
const {data} = props;
const router = useRouter()
// If the page is not yet generated, this will be displayed
// initially until getStaticProps() finishes running
if (router.isFallback) {
return <div>Loading...</div>
}
if (!data) {
return (
<>
<Head>
<meta name="robots" content="noindex"/>
</Head>
<DefaultErrorPage statusCode={404}/>
</>
)
}
return <DataView {...data} />;
}
推荐阅读
- c# - SpeechSynthesizer 抛出 System.InvalidOperationException
- python - 从不同的文件夹级别导入一个类 - Python
- c# - Windows 命令行参数转义
- python - 如何将生成的 hdf5 模型合二为一?
- javascript - 如何获取 Rails 表单中文本字段的新值?
- javascript - 以对象的字段作为参数获取 javascript 对象的字段名称
- excel - 下面的 VBA 代码在我的家用笔记本电脑(Excel 2016)上运行,但在我的工作笔记本电脑(Excel 2010)上运行,错误“438”
- javascript - Reactjs 获取 URL 路径名 id
- python - 用于获取可能路径的 MxN 网格(矩阵)问题
- python - 在wxpython中一个接一个地切换工具栏小部件4次的逻辑是什么?