按需重新验证让你能够恰好在数据变化时使缓存/静态页面失效——而不是等待基于时间的间隔。它是基于时间的 ISR (revalidate: N) 的精确补充。
基于时间对比按需
tsx
revalidate = ;
基于时间的 ISR 很简单但不完美:时间过短 = 不必要的重新生成;时间过长 = 内容过期。按需通过在实际发生更改时从你自己的代码触发重新验证来解决这一问题。
import { revalidatePath, revalidateTag } from "next/cache";
// 1. Tag your fetches, then invalidate by tag
await fetch("https://api/posts", { next: { tags: ["posts"] } });
revalidateTag("posts"); // refresh EVERY page/fetch tagged "posts"
// 2. Or invalidate a specific path
revalidatePath("/blog/my-post");
// app/api/revalidate/route.ts — called by your CMS when an editor publishes
import { revalidateTag } from "next/cache";
import { NextRequest, NextResponse } from "next/server";
export async function POST(req: NextRequest) {
const secret = req.nextUrl.searchParams.get("secret");
if (secret !== process.env.REVALIDATE_SECRET) { // verify it's really your CMS
return NextResponse.json({ ok: false }, { status: 401 });
}
revalidateTag("posts"); // rebuild affected pages now
return NextResponse.json({ revalidated: true });
}
流程:编辑在 CMS 中发布 → CMS 调用你的 webhook → revalidateTag("posts") 使缓存失效 → 下一个访问者获得新生成的静态 HTML。页面保持静态快速并且在发布时立即更新。
"use server";
export async function createPost(data) {
await db.post.create({ data });
revalidateTag("posts"); // user sees their new post immediately
}
按需重新验证给你带来了圣杯:具有实时新鲜度的静态性能。
与其猜测重新验证间隔,不如在内容实际更改时精确使其失效——通过 webhooks (CMS 发布) 或 Server Action 变更之后——使用 revalidateTag/revalidatePath。
它消除了内容过期和浪费性的过度生成,使 ISR 对于不可预测更新的内容切实可行。