Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to clear/delete cache in NextJs?

I have a product page at /products/[slug].js

and I use Incremental Static Generation for a wordpress/graphql site:

export async function getStaticProps(context) {

    const {params: { slug }} = context

    const {data} = await client.query(({
        query: PRODUCT_SLUG,
        variables: { slug }
    }));

    return {
        props: {
            categoryName: data?.productCategory?.name ?? '',
            products: data?.productCategory?.products?.nodes ?? []
        },
        revalidate: 1
    }

}

export async function getStaticPaths () {
    const { data } = await client.query({
        query: PRODUCT_SLUGS,
    })

    const pathsData = []

    data?.productCategories?.nodes && data?.productCategories?.nodes.map((productCategory) => {
        if (!isEmpty(productCategory?.slug)) {
            pathsData.push({ params: { slug: productCategory?.slug } })
        }
    })

    return {
        paths: pathsData,
        fallback: true,
    }
}

Everything works as expected except one thing. If I delete a product from wordpress which was previously published, NextJs serves the cached page instead of showing 404 - Not found page, and I think this is how it is supposed to work, meaning that if something isn't rebuilt, show the previous (stale) page.

But how can I completely remove the cache for a specific product which has been deleted and it is not fetched again from the PRODUCT_SLUGS query ?

I have read the fallback options: true, false, blocking but none of them seems to work.

Is there a solution to this, either a next.config.js configuration or another work around ?

like image 228
entropyfeverone Avatar asked Jul 19 '21 17:07

entropyfeverone


1 Answers

I think this is possible starting from [email protected] using this feature On-demand Incremental Static Regeneration https://nextjs.org/blog/next-12-1#on-demand-incremental-static-regeneration-beta

basically you can define an api path in this way

// pages/api/revalidate.js

export default async function handler(req, res) {
  // Check for secret to confirm this is a valid request
  if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
    return res.status(401).json({ message: 'Invalid token' })
  }
  const PRODUCT_SLUGS = req.query.product_slug;

  try {
    await res.unstable_revalidate(`/products/${PRODUCT_SLUGS}`)
    return res.json({ revalidated: true })
  } catch (err) {
    // If there was an error, Next.js will continue
    // to show the last successfully generated page
    return res.status(500).send('Error revalidating')
  }
}

Using this api path you can invalidate the cache for a specific product

like image 193
dna Avatar answered Oct 05 '22 23:10

dna