Skip to content

tommarshall/next-kontent-on-demand-isr-demo

Repository files navigation

Next.js & Kontent On-Demand Incremental Static Regeneration (ISR) Demo

A demo application showcasing how Next.js on-demand incrementation static regeneration can be used in combination with Kontent.ai webhooks to revalidate pages when content changes are published.

This project is based on the official Next.js cms-kontent example.

A full write up of on-demand ISR and the considerations for real world sites can be found on the Kontent.ai blog: How to improve cache efficiency and reduce costs with Next.js on-demand ISR.

Requirements

Setup

Clone the repo

git clone git@github.com:tommarshall/next-kontent-on-demand-isr-demo.git
cd next-kontent-on-demand-isr-demo/

Scaffold the Next.js environment configuration file.

cp .env.local.example .env.local

Create a new Kontent project

Create a new, empty project in Kontent via the web UI.

Then set the following variables in .env.local:

  • KONTENT_PROJECT_ID - Should be the Project ID in Project settings > API keys.
  • KONTENT_PREVIEW_API_KEY - One of the Preview API keys in Project settings > API keys.
  • KONTENT_PREVIEW_SECRET - Can be any random string (but avoid spaces), like NOT_A_SECRET - this is used for Preview Mode.
  • KONTENT_WEBHOOK_SECRET - Leave blank, we'll set this later.

Configure the Preview URLs for the Post type, if you want to use it:

http://localhost:3000/api/preview?secret=NOT_A_SECRET&slug={URLslug}

Import the demo dataset into the Kontent project

Import the demo project into Kontent using kontent-cli. You'll need to enable the Management API in the project settings to generate the API key.

yarn run kontent backup --action=restore --apiKey=<Management API key> --projectId=<Project ID> --zipFilename=kontent-backup

Then publish all the imported items via the Kontent web UI.

Configure the Kontent webhook

If working locally, use ngrok to create a public URL with a tunnelled connection to the Next.js port on your local machine.

ngrok http 3000

Create a new webhook in the project via Project settings > Webhhooks with the URL address set to /api/revalidate api route with the ngrok origin, e.g.

https://5048-86-151-48-86.ngrok.io/api/revalidate

Then set the KONTENT_WEBHOOK_SECRET variable in .env.local using the webhook secret generated by Kontent.

Install the packages

Install the Next.js node modules via yarn.

yarn install

Testing the on-demand revalidation

Start the Next.js client application in production mode.

yarn build
yarn start

You should now be able to see the example blog application in your browser at http://localhost:3000.

Important: We need to use yarn build and yarn start rather than yarn dev to test the on-demand revalidation as yarn dev calls getStaticProps on each request, regardless of the incremental static regeneration revalidate config.

Publish a change to any post in Kontent.

The ngrok logs in the terminal should show a 200 OK from the webhook request.

Refresh the corresponding post page in your browser and you should see your change. Success! 🙌

Known Limitations

URL Slug Changes

Next.js' revalidate() requires a URL path to revalidate a page.

Kontent's webhook requests do not contain any detail regarding the change, nor does the Delivery API allow us to ask for older versions of a content item.

So if we change the URL slug of content item in Kontent, the webhook handler API route generates the URL path using the new URL slug value, which causes revalidate() to error, as it cannot find a page to revalidate for that new path.

If fallback: true or fallback: blocking is set for the page route then the page will be visible at the new path, but unless we set a revalidate duration for thge page route the page will continue to serve from the old path as well.

Wider Revalidation

Neither the pages/index.js nor the pages/posts/[slug].js getStaticProps in this example declare a revalidate duration. This means Next.js will use the default value of false (no revalidation) and only revalidate the page on-demand, when revalidate() is called.

Currently, the api/revalidate.js endpoint will only revalidate the immediate post page when a post is changed. That's fine for this proof-of-concept, but for production we'd need to consider that:

  • Posts appear on the homepage.
  • Posts appear in the 'more stories' section on other post pages.
  • Author content might also change.

To resolve this we'd either need to set a sensible revalidate duration for both the home and post page routes, or implement additional logic within the api/revalidate.js endpoint to handle these cases via revalidate().

About

A demo application showcasing how Next.js on-demand incremental static regeneration (ISR) can be used with Kontent.

Topics

Resources

Stars

Watchers

Forks