71 lines
2.2 KiB
TypeScript
71 lines
2.2 KiB
TypeScript
import { revalidatePath, revalidateTag } from "next/cache";
|
|
import { NextRequest, NextResponse } from "next/server";
|
|
|
|
type RevalidateBody = {
|
|
/** Revalidate a fetch cache tag (portfolios, blogs, portfolio:slug, blog:slug, …). */
|
|
tag?: string;
|
|
/** Revalidate a path (/projects/foo, /, …). */
|
|
path?: string;
|
|
/** Shorthand: portfolios | blogs | all */
|
|
scope?: "portfolios" | "blogs" | "all";
|
|
};
|
|
|
|
/**
|
|
* On-demand cache purge — call after CMS publish/update.
|
|
*
|
|
* POST /api/revalidate
|
|
* Header: x-revalidate-secret: <REVALIDATE_SECRET>
|
|
* Body (JSON, optional): { "scope": "all" } | { "tag": "portfolios" } | { "path": "/projects/item" }
|
|
*
|
|
* nginx may still serve cached HTML for up to its TTL (5m) unless purged separately.
|
|
*/
|
|
export async function POST(req: NextRequest) {
|
|
const secret = process.env.REVALIDATE_SECRET;
|
|
if (!secret) {
|
|
return NextResponse.json({ ok: false, error: "REVALIDATE_SECRET not configured" }, { status: 503 });
|
|
}
|
|
|
|
const provided =
|
|
req.headers.get("x-revalidate-secret") ?? req.nextUrl.searchParams.get("secret");
|
|
if (provided !== secret) {
|
|
return NextResponse.json({ ok: false, error: "Unauthorized" }, { status: 401 });
|
|
}
|
|
|
|
let body: RevalidateBody = {};
|
|
try {
|
|
body = (await req.json()) as RevalidateBody;
|
|
} catch {
|
|
body = {};
|
|
}
|
|
|
|
const scope = body.scope ?? "all";
|
|
const revalidated: string[] = [];
|
|
|
|
if (body.tag) {
|
|
revalidateTag(body.tag);
|
|
revalidated.push(`tag:${body.tag}`);
|
|
} else if (body.path) {
|
|
revalidatePath(body.path);
|
|
revalidated.push(`path:${body.path}`);
|
|
} else if (scope === "portfolios" || scope === "all") {
|
|
revalidateTag("portfolios");
|
|
revalidatePath("/");
|
|
revalidatePath("/projects");
|
|
revalidatePath("/aboutus");
|
|
revalidatePath("/atelier");
|
|
revalidatePath("/raoofi-home");
|
|
revalidated.push("scope:portfolios");
|
|
}
|
|
|
|
if (scope === "blogs" || scope === "all") {
|
|
revalidateTag("blogs");
|
|
revalidateTag("blogs:news");
|
|
revalidatePath("/news");
|
|
revalidatePath("/blog");
|
|
revalidatePath("/news-and-blog");
|
|
revalidated.push("scope:blogs");
|
|
}
|
|
|
|
return NextResponse.json({ ok: true, revalidated, at: new Date().toISOString() });
|
|
}
|