Next.js App Router + Sanity使用revalidateTag()缓存刷新异常问题
Next.js App Router + revalidateTag() + Sanity 缓存刷新异常问题
我正在尝试让Next.js App Router结合revalidateTag()与Sanity配合工作,但结果要么完全不可预测,要么我完全误解了某些机制。已经花5天调试并搭建多个项目,目前发现以下情况:
- 项目1:基础配置(文章、页面、分类、[slug]动态页面),可正常工作。
- 项目2:配置接近项目1(新增带额外标签的子页面)。标记
job或benefit的简单标签请求在/和/post-a-job路由无法刷新,但在/contract/[slug]路由正常;job:${params.slug}这类带slug的标签全部正常。 - 项目3&4:与项目2类似,新增团队成员、导航链接等schema类型,问题推测与项目2一致,但无法明确。
额外明确问题:带homepage标签的首页类型包含导航链接,(site)/page.tsx及Navbar、Footer组件均有标记homepage的请求,组件请求可正常刷新,但/路由从未刷新。
所有项目中Sanity webhook调用刷新API路由均成功,参数符合预期,但暂无法调试revalidateTag()实际调用。尚未尝试集成预览和草稿模式,不确定是Sanity、Next.js的Bug还是自身配置问题。
补充上下文
示例请求(/路由无法刷新)
const jobs = await sanityFetch<Job[]>({ query: jobsQuery, tags: [`job`], });
示例请求(/[slug]路由可正常刷新)
const page = await sanityFetch<Page>({ query: pagesBySlugQuery, params: { slug: params.slug }, tags: [`page:${params.slug}`], });
sanityFetch函数
export async function sanityFetch<QueryResponse>({ query, params = DEFAULT_PARAMS, tags = DEFAULT_TAGS, }: { query: string; params?: QueryParams; tags: string[]; }): Promise<QueryResponse> { return client.fetch<QueryResponse>(query, params, { // 仅在配置了重验证webhook时缓存 cache: revalidateSecret ? "force-cache" : "no-store", next: { //revalidate: 30, // 基于时间的简单重验证 tags, // 基于标签的重验证 }, }); }
刷新路由处理器
import { revalidateTag } from "next/cache"; import { NextResponse, type NextRequest } from "next/server"; import { parseBody } from "next-sanity/webhook"; import { revalidateSecret } from "@/lib/sanity.api"; export async function POST(req: NextRequest) { try { const { body, isValidSignature } = await parseBody<{ _type: string; slug?: string | undefined; }>(req, revalidateSecret); if (!isValidSignature) { const message = "Invalid signature"; return new Response(message, { status: 401 }); } if (!body?._type) { return new Response("Bad Request", { status: 400 }); } revalidateTag(body._type); if (body.slug) { revalidateTag(`${body._type}:${body.slug}`); } return NextResponse.json({ status: 200, revalidated: true, now: Date.now(), body, }); } catch (err: any) { console.error(err); return new Response(err.message, { status: 500 }); } }
内容的提问来源于stack exchange,提问作者David Levai
相关产品推荐
相关产品推荐

