Intro
If you made a headless website or e-commerce, you've run into the issue that it didn't immediately refresh live after you changed your content? Relax; you're not alone!
I've been working on a cool MedusaJS project, and we had the problem that our SEO experts were working in Strapi and didn't see their changes... Annoying when there are some minor or important edits you want to see live/in realtime.
How does it work?
The solution is quite simple. Next.js has a feature called Incremental Static Regeneration. This allows you to refresh the static props every x seconds, or what we desire: on-demand revalidation. This function can be triggered by the Strapi Webhook Events.
On demand revalidation
In short, you execute a revalidate
function with the correct URL path to perform the revalidation.
A small example:
await res.revalidate('/path-to-revalidate')
return res.json({ revalidated: true })
One downside, you can only revalidate a specific path. No wildcards or whatsoever are allowed. Our goal is to revalidate a strapi content entry every time we update, publish or create it.
Strapi webhook events
As simple as can be, register a webhook, fill in the correct URL, enable the right events, and you're ready to go!
Requirements
To have this all working, we need one thing. Ensure the slug/path is known or can be generated with strapi information!
In our example, we set a slug
to every content type and made sure the content type name corresponds with our slug on the frontend.
( oke... fair enough.. one exception for pages )
Let's create our solution!
First, we'll create the next.js solution. Our projects always use Typescript. For a javascript version, remove the types in the function variables.
Next.js (Medusa.js with Next.js in our case)
/src/pages/api/revalidate.tsx
import type { NextApiRequest, NextApiResponse } from "next"
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
// or a secret from an environment variable
if (req.query.secret !== "SomeRandomSecret")
return res.status(401).json({ message: "Invalid token" })
try {
const { event, entry, model } = req.body
switch (event) {
case "entry.update":
case "entry.create":
case "entry.publish":
await res.revalidate(
`${model !== "page" ? "/" + model : ""}/${entry?.slug ?? ""}`
)
break
default:
return res.status(500).send(`Invalid event "${event}"`)
break
}
return res.json({ revalidated: true })
} catch (err) {
return res.status(500).send("Error revalidating")
}
}
For this tutorial, I didn't set an Authorization
header with bearer, but I do recommend this!
In our code, we check if the secret is valid, which event is fired, and what path to revalidate.
What if my paths don't correspond with my models?
No worries. You could setup a small object which maps your model to the correct path. Here is a quick example:
const pathMaps = { blogContent: '/blog' }
//...
await res.revalidate(
</span><span class="p">${</span><span class="nx">pathMaps</span><span class="p">[</span><span class="nx">model</span><span class="p">]</span><span class="o">??</span><span class="dl">""</span><span class="p">}</span><span class="s2">/</span><span class="p">${</span><span class="nx">entry</span><span class="p">?.</span><span class="nx">slug</span> <span class="o">??</span> <span class="dl">""</span><span class="p">}</span><span class="s2">
)
Strapi
Navigate to Settings --> Webhooks and click on Create new webhook
.
Fill the fields accordingly with your domain and hit save.
Done
That's it; go get yourself a coffee to celebrate! Whenever you change something in Strapi, your static props are invalidated in your Next.js frontend!
Top comments (3)
Thanks for writing this guide! I know some Medusa community members have run into similar issues.
Glad I could help :) Love the MedusaJS discord channel!
Glad to have you as part of our community! 🙌🏻