kit icon indicating copy to clipboard operation
kit copied to clipboard

"revalidatePath" for Vercel ISR On-Demand Revalidation?

Open leoj3n opened this issue 1 year ago • 0 comments

Describe the problem

If you check the Vercel docs about on-demand revalidation for ISR, you will see they show this example for Next.js:

import { revalidatePath } from 'next/cache';
 
export async function GET(request) {
  const { searchParams } = new URL(request.url);
  if (searchParams?.secret !== process.env.MY_SECRET_TOKEN) {
    return new Response(`Invalid credentials`, {
      status: 500,
    });
  }
  revalidatePath('/blog-posts');
  return new Response(
    {
      revalidated: true,
      now: Date.now(),
    },
    {
      status: 200,
    },
  );
}

Where they import { revalidatePath } from 'next/cache'; but for the SvelteKit example there is no such function:

import { BYPASS_TOKEN } from '$env/static/private';
 
export const config = {
  isr: {
    expiration: 10,
    bypassToken: BYPASS_TOKEN,
  },
};

I suppose you can manually create a path like src/routes/api/revalidate/+server.ts:

import {error, json, type RequestHandler} from "@sveltejs/kit";
import {isValidSignature, SIGNATURE_HEADER_NAME} from "@sanity/webhook";
import { env } from "$env/dynamic/private";

type ResponseType = {
  _id?: string,
  slug?: string,
  _type?: string,
}

/**
 * Revalidates a slug.
 *
 * @param slug
 *   The slug to revalidate.
 */
async function revalidateSlug(slug: string): Promise<boolean> {
  // Set a delay to allow Sanity data to correctly propagate.
  await new Promise(resolve => setTimeout(resolve, 2000));
  console.log(`Revalidating: ${env.SITE_URL}/${slug}`);
  const res = await fetch(`${env.SITE_URL}/${slug}`, {
    cache: 'no-store',
    headers: {
      'x-prerender-revalidate': env.BYPASS_TOKEN,
    }
  });
  if (!res.ok) {
    console.log(`Could not revalidate ${env.SITE_URL}/${slug}`);
  }
  return res.ok;
}

/** @type {import('./$types').RequestHandler} */
export const POST: RequestHandler = async ({ request }) => {
  const signature = request.headers.get(SIGNATURE_HEADER_NAME) ?? '';
  const body = await request.clone().json() as ResponseType;

  if (!(await isValidSignature(JSON.stringify(body), signature, env.BYPASS_TOKEN))) {
    throw error(403, "Forbidden")
  }

  if (body?.slug) {
    const ok = await revalidateSlug(body.slug);
    if (body?._type === 'post') {
      await revalidateSlug('blog');
    }
    return json({ok});
  }

  throw error(404, "Slug not found")
}

(taken from https://www.megamashmedia.com/blog/how-to-setup-on-demand-revalidation-with-sveltekit-sanity-and-vercel)

But I'm wondering if this isn't something SvelteKit already includes like seen in the NextJS example?

Describe the proposed solution

If this doesn't exist in SvelteKit, I'm wondering if it would be a nice to have worth adding?

Alternatives considered

No response

Importance

nice to have

Additional Information

No response

leoj3n avatar Mar 24 '24 16:03 leoj3n