Skip to content

Commit c9f80f7

Browse files
committed
add sanity revalidation webhook
1 parent 0e2086d commit c9f80f7

4 files changed

Lines changed: 80 additions & 4 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@scstanton20/portfolio-v2",
3-
"version": "1.7.12",
3+
"version": "1.7.13",
44
"private": true,
55
"type": "module",
66
"scripts": {

src/app/(main)/connect/page.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ async function getConnectPhoto() {
1111
alt,
1212
image
1313
}`;
14-
return await sanityClient.fetch<ConnectPhoto[]>(connectphotoquery);
14+
return await sanityClient.fetch<ConnectPhoto[]>(connectphotoquery, {}, {
15+
next: { tags: ['connectphoto'] }
16+
});
1517
}
1618

1719
export default async function Connect() {

src/app/(main)/page.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ async function getProjects() {
1717
description[]{...},
1818
image
1919
}`;
20-
return await sanityClient.fetch<Project[]>(projectsquery);
20+
return await sanityClient.fetch<Project[]>(projectsquery, {}, {
21+
next: { tags: ['projects'] }
22+
});
2123
}
2224

2325
async function getCertifications() {
@@ -28,7 +30,9 @@ async function getCertifications() {
2830
issuer,
2931
receivedDate
3032
}`;
31-
return await sanityClient.fetch<Certification[]>(certquery);
33+
return await sanityClient.fetch<Certification[]>(certquery, {}, {
34+
next: { tags: ['certifications'] }
35+
});
3236
}
3337

3438
export default async function Home() {

src/app/api/revalidate/route.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { revalidateTag } from 'next/cache';
2+
import { NextRequest, NextResponse } from 'next/server';
3+
4+
type SanityWebhookPayload = {
5+
_type?: string;
6+
_id?: string;
7+
};
8+
9+
export async function POST(request: NextRequest) {
10+
const timestamp = new Date().toISOString();
11+
console.log(`[${timestamp}] 🔔 Webhook received from Sanity`);
12+
13+
// Validate secret token from env var
14+
const secret = request.nextUrl.searchParams.get('secret');
15+
16+
if (secret !== process.env.SANITY_REVALIDATE_SECRET) {
17+
console.log(`[${timestamp}] ❌ Invalid token provided`);
18+
return NextResponse.json({ message: 'Invalid token' }, { status: 401 });
19+
}
20+
21+
try {
22+
// Parse the webhook payload to determine what to revalidate
23+
const body = await request.json().catch(() => ({})) as SanityWebhookPayload;
24+
const { _type, _id } = body;
25+
26+
console.log(`[${timestamp}] 📦 Content type: ${_type || 'unknown'}, ID: ${_id || 'unknown'}`);
27+
28+
const revalidatedTags: string[] = [];
29+
30+
// Revalidate based on content type
31+
// Note: In Next.js 16, revalidateTag requires a second argument (cache profile)
32+
// Using empty string for default behavior
33+
if (_type === 'project') {
34+
revalidateTag('projects', '');
35+
revalidatedTags.push('projects');
36+
} else if (_type === 'certification') {
37+
revalidateTag('certifications', '');
38+
revalidatedTags.push('certifications');
39+
} else if (_type === 'connectphoto') {
40+
revalidateTag('connectphoto', '');
41+
revalidatedTags.push('connectphoto');
42+
} else if (_type === 'experience') {
43+
revalidateTag('experience', '');
44+
revalidatedTags.push('experience');
45+
} else {
46+
// If no type specified or unknown type, revalidate everything
47+
console.log(`[${timestamp}] ⚠️ Unknown content type, revalidating all tags`);
48+
revalidateTag('projects', '');
49+
revalidateTag('certifications', '');
50+
revalidateTag('connectphoto', '');
51+
revalidateTag('experience', '');
52+
revalidatedTags.push('projects', 'certifications', 'connectphoto', 'experience');
53+
}
54+
55+
console.log(`[${timestamp}] ✅ Successfully revalidated tags: ${revalidatedTags.join(', ')}`);
56+
57+
return NextResponse.json({
58+
revalidated: true,
59+
tags: revalidatedTags,
60+
now: Date.now(),
61+
message: `Successfully revalidated tags: ${revalidatedTags.join(', ')}`,
62+
});
63+
} catch (err) {
64+
console.error(`[${timestamp}] ❌ Error revalidating:`, err);
65+
return NextResponse.json(
66+
{ message: 'Error revalidating', error: String(err) },
67+
{ status: 500 }
68+
);
69+
}
70+
}

0 commit comments

Comments
 (0)