With the latest Next.js 12.1 version finally we got one of the most powerful missing feature: on-demand ISR 😮!
Thanks to this you can revalidate your SSG pages on the fly without rebuild all the site or without waiting the scheduled time set in the revalidate option as we were used to until today.
I love Sanity as headless CMS for its user friendly studio and for the power of its tools and plugins; I used to install the sanity-plugin-vercel-deploy plugin, very useful to update my SSG sites hosted on Vercel but this was meaning trigger a new build and redeploy all the entire site (I never used ISR with its revalidate option because, on bigger sites, the build cost would be too high).
One of the Sanity great feature is how they manage webhooks: you can trigger an URL after you edit your data specifying which document type and what send as payload, simply querying your database with its GROQ query language!
Now you can add a new API URL in your Next.js web app to revalidate your page content on-demand and request it by the Sanity webhook trigger 🤩.
For example, in your blog, imagine to fix a post typo on the Sanity studio and, after less a second, see your edit live. Cool right? First of all you need to add a new API endpoint on your web app, adding a file like this on the pages/api
folder (yes I 🥰 TypeScript too):
import { isValidRequest } from "@sanity/webhook"
import type { NextApiRequest, NextApiResponse } from "next"
type Data = {
message: string
}
const secret = process.env.SANITY_WEBHOOK_SECRET
export default async function handler(req: NextApiRequest, res: NextApiResponse<Data>) {
if (req.method !== "POST") {
console.error("Must be a POST request")
return res.status(401).json({ message: "Must be a POST request" })
}
if (!isValidRequest(req, secret)) {
res.status(401).json({ message: "Invalid signature" })
return
}
try {
const {
body: { type, slug },
} = req
switch (type) {
case "post":
await res.revalidate(`/news/${slug}`)
return res.json({ message: `Revalidated "${type}" with slug "${slug}"` })
}
return res.json({ message: "No managed type" })
} catch (err) {
return res.status(500).send({ message: "Error revalidating" })
}
}
In this function I accept a POST request with a type
and a slug
as payload; there are three main points to pay attention:
- validate the Sanity webhook secret, so we are safe to accept the request
- call the
revalidate
method passing the path that we need to purge as the argument - set the
useCdn
Sanity client option tofalse
to allow to get fresh content after the revalidate call (the webhook is too fast 😅)
This is how I set my Sanity webhook:
I chosen to send the document type on the payload so I can manage the revalidate with a unique endpoint but you are free to follow your best needs.
This new Next.js feature is the beginning of a new era:
- you don't need to SSR your pages but keep them on your CDN, with no power consumption 💚 and #JAMstack compliant
- updates will be immediately online, no more building wait time
- your editors will be happy to preview, publish and check contents on the fly!
Thanks Vercel 🔼!
Top comments (7)
You should update this now that it is no longer unstable.
Thanks, I updated the post 😉
Greate guide, posted it on nextjs channel of sanity-io-land slack. Tks!
Great guide, I have found this doesn't yet work on netlify at the moment, just Incase people wonder why they can't get it to work.
Exactly what I'm implementing in a blog, I can't believe somebody already wrote a blog post about this. I'll surely try out your method.
Thx for sharing. Really great guide. I'll test is also in my next project
Very helpful! Thank, you 🤓