@@ -22,6 +22,51 @@ const defaultRevalidateOptions: RevalidateBody = {
2222 feedIds : [ ] ,
2323} ;
2424
25+ /**
26+ * GET handler for the Vercel cron job that revalidates all feed pages once a day.
27+ * Vercel automatically passes Authorization: Bearer <CRON_SECRET> with each invocation.
28+ * Configured in vercel.json under "crons" (schedule: 0 9 * * * = 4am EST / 9am UTC).
29+ */
30+ export async function GET ( req : Request ) : Promise < NextResponse > {
31+ const authHeader = req . headers . get ( 'authorization' ) ;
32+ const cronSecret = process . env . CRON_SECRET ;
33+
34+ if ( cronSecret == null ) {
35+ return NextResponse . json (
36+ { ok : false , error : 'Server misconfigured: CRON_SECRET missing' } ,
37+ { status : 500 } ,
38+ ) ;
39+ }
40+
41+ if ( authHeader !== `Bearer ${ cronSecret } ` ) {
42+ return NextResponse . json (
43+ { ok : false , error : 'Unauthorized' } ,
44+ { status : 401 } ,
45+ ) ;
46+ }
47+
48+ try {
49+ revalidateTag ( 'guest-feeds' , 'max' ) ;
50+ revalidatePath ( '/[locale]/feeds/[feedDataType]/[feedId]' , 'layout' ) ;
51+ console . log (
52+ '[cron] revalidate /api/revalidate: all-feeds revalidation triggered' ,
53+ ) ;
54+ return NextResponse . json ( {
55+ ok : true ,
56+ message : 'All feeds revalidated successfully' ,
57+ } ) ;
58+ } catch ( error ) {
59+ console . error (
60+ '[cron] revalidate /api/revalidate: revalidation failed:' ,
61+ error ,
62+ ) ;
63+ return NextResponse . json (
64+ { ok : false , error : 'Revalidation failed' } ,
65+ { status : 500 } ,
66+ ) ;
67+ }
68+ }
69+
2570export async function POST ( req : Request ) : Promise < NextResponse > {
2671 const expectedSecret = nonEmpty ( process . env . REVALIDATE_SECRET ) ;
2772 if ( expectedSecret == null ) {
0 commit comments