DEV Community

Cover image for Strapi + Next.js refresh static props like it's cache
Bram Hammer
Bram Hammer

Posted on • Updated on

Strapi + Next.js refresh static props like it's cache

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 })
Enter fullscreen mode Exit fullscreen mode

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")
    }
}

Enter fullscreen mode Exit fullscreen mode

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(
    `${pathMaps[model]??""}/${entry?.slug ?? ""}`
)
Enter fullscreen mode Exit fullscreen mode

Strapi

Navigate to Settings --> Webhooks and click on Create new webhook.
Settings --> Webhooks strapi
Fill the fields accordingly with your domain and hit save.
Strapi webhook setup

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!

Cat programmer

Resources:

Latest comments (3)

Collapse
 
shahednasser profile image
Shahed Nasser • Edited

Thanks for writing this guide! I know some Medusa community members have run into similar issues.

Collapse
 
fullstak profile image
Bram Hammer

Glad I could help :) Love the MedusaJS discord channel!

Collapse
 
shahednasser profile image
Shahed Nasser

Glad to have you as part of our community! 🙌🏻