Within this tutorial, you will learn how to set-up, code and configure live preview for Contentful CMS. For this tutorial, I built the connecting headless website using NextJS, with app router and server components, however, I will try to make this guide as Framework agnostic as possible.

I must admit that I didn't find setting up live preview the easiest task in the world. This article took me a few days to prep for as the set-up steps differ fairly widely depending on if you use Rest, GraphQL, server component, SSG, etc.. As I struggled to find a simple guide that covered all the hidden gotchas and caveats , to help prevent you banging your head against the same wall as I did, I thought I'd write this guide to make it easier for someone to set things up, so read on if you want to set-up live preview without needing to waste hours of your life in debugging hellπŸ”₯πŸ”₯πŸ”₯

Contentful Live Preview Overview

Within the latter part of 2023, Contentful released live preview in order to address frustrations that some content editors had with creating content for a website using a headless CMS. As content created within a headless CMS is designed to be omni-channel, meaning it can be shared between a website, mobile app, etc.. having a direct one-on-one webpage preview made less sense compared to a traditional CMS. For some teams the existing preview was fine, however, as a lot of headless CMS content is used within a website, not having a specific inline preview annoyed some editors.

Before Contentful released live preview, assuming the development team built the CMS using certain standards, an editor could always preview the page in real-time with a click of a button. This button click would launch the clients website in a new browser tab, and assuming the site used the correct tokens, preview content could be viewed in real-time.

Opening a site within a new tab is not the only way to deal with preview within a CMS. Companies like StoryBlok and even Wordpress have always provided inline on-page editing and with live preview Contentful now joins this list. In terms of technical set-up for live preview there are three specific things that a developer will need to consider first:

  • Real-time content updates
  • On-page property highlighting
  • Hosting

Real-time content updates (Rest vs GraphQL ): This feature does what it says on the tin, your preview content should update in real time within the preview screen.

If you want to save yourself several hours of wasted debugging frustrations, then the important thing took understand is that the method you use to query the CMS in code determines if this will work or not.

If you want the content to update in real-time on preview, use GraphQL in your code to get data. If you look at the Contentful demo site on their GitHub here, you will see a few examples. The ones that use GraphQL update in real-time, the ones that use REST don't.

In order to write this article, I wanted to get live content updates working using REST and Graph, however, I failed. I created my own demo site, which you can clone from here to test everything out. That site contained two pages. Both pages use the same preview API calls, the same components, the only difference is one makes a call via REST the other uses GraphQL.

The GraphQL preview works in real-time, the REST one doesn't. So if you want to set preview up with REST and its not working, switch to GraphQL and save yourself a bunch of time! It probably is possible to get live preview working with REST, however, you are probably going to have to use web hooks. Just in terms of code management, using GraphQL will be way easier compared to setting up a hook for each content type and then creating corresponding code to deal with all the updates within your site, so my tip is stick with GraphQL if preview is important.

How To Set-up Live Preview Inline Editing: The next preview consideration is the property inspection feature. Within your headless site, its possible for you to add special Contentful attributes within your HTML. When added, if a content editor clicks on some text within live preview, Contentful will automatically open that property within the sidebar.

The important thing to note here is that you do not need to implement this feature to get some level of preview. If you want to enable this feature, be aware that it does involve writing and managing a lot of potentially flaky code. Enabling this feature is not just simply enabling it for the entire website, instead, you will need to write code for every property on every content type that gets created.

In terms of implementation, for each page and component you create that renders content from the CMS, you will need to update your HTML to call a Contentful function and pass in the corresponding property name. This is where the maintenance headache kicks in.

Every time an editor either changes a property name, deletes a property, or even adds a new property within the CMS, you will need to write some corresponding preview specific code for this feature. On a large site that contains lots of content types, enabling this feature will add a significant amount of dev and maintenance work for the dev team and it will be very easy for your website and your content models to become out of sync.

Before implementing this feature, I would check with the content team if they really need it. Keep in mind, developers are more expensive than editors. Even though this is a cool feature that will save editors a few seconds here and there when creating content, is the trade-off worth the many hours of effort required by the dev team to set it up and maintain it?

Hosting: The last thing to consider is hosting. As preview content could be sensitive, I always recommend setting up a new site within your hosting provider just for preview.

It is possible to toggle production and preview on the same hosted app, however, it adds more hassle. My recommendation is to have a production site and then within Contentful point the preview to a completely separate site! Having two completely separate site also means you can separate out your Contentful prod and preview access tokens. It also means you can tweak preview without taking your live site down! As your preview site will have minimal traffic, the added hosting cost should be minimal!

How To Set Up Contentful Live Preview SDK

If you implement the tips above, then setting up preview should be pretty easy. In terms of implementation there are several steps you will need to follow:

  • Install the Contentful Live Preview SDK
  • Set-up the preview API/redirect
  • Add a live preview object to the page and enabled it
  • Add the property inspection code (if you decide to implement this feature)
  • Configure the preview settings within Contentful

Set-up Environment Variables: To get your website to talk to the CMS you will need to create and add some access tokens within your site. I won't cover how create the tokens within Contentful here, however, these are the variables you will likely need:

Create a Preview API within your website: In order to see content update in real-time on a page, the CMS will need a way to talk to your website so that the page can refresh automatically. This API call is the code that enables this magic to work!

Without following this step, the content will not update in real-time and instead a content editor would need to manually press the page refresh button in the preview.

Remember I am using server-components and app router for NextJS for this demo. This means I need to create an API end-point within the app folder:

api ➜ api ➜ enable-draft-post ➜ route.js

In this example, enabled-draft-post will be the name of the API call. You can rename this folder to what makes sense for you. The thing to note that this will impact the URL you add for preview within the CMS! The code for my route.js looks like this:

Install the Contentful Live Preview SDK: The next step is to install the Contentful Live Preview package:

Enabling Contentful Live Mode Within Your Website: After installing the live preview SDK, the next step is to enable preview mode. Note, this mode should be disabled and turned off in production! The best place to enable live preview is within your websites main layout template file. In a NextJS site using app router, this file is usually located here:

api ➜ layout.js

If you look online there are different ways to add this code. It will depend if you use server-component, normal components, etc.. If the code below does not work, you can call the function directly, rather than use it like a component.

This code is pretty self-explanatory, you wrap your whole sites HTML within this component called ContentfulLivePreviewProvider. This component has two preview settings you can enable:

  • enableLiveUpdates this enables the live preview code. If you forget to do this you will get an error within Contentful when trying to preview
  • enableInspectorMode this enables the inspector. If you do not do this, when editors click on content in preview nothing will happen!

Another important thing to note is the call @contentful/live-preview/style.css on line 2. You need to enable this in order for the preview CSS to work correctly!

Also note the call to draftMode, this is a NextJS thing but works with a headless CMS context and lets you know in code if you are in preview mode or not!

Add live preview to a page: After enabling preview on a site-level, the next thing is to set things up at a page-level!

This code will enable the live content update mode to work. I have omitted the code to call Contentful to get the content type data from the CMS within this tutorial for brevity, however, you can find it in my Github repo

Remember, you will need to use GraphQL here to get the data otherwise when editors add content the preview page will not update in real-time and they will manually need to click the reload button to see their changes!

Making live preview work is simple, take your normal Contentful page object and pass it to useContentfulLiveUpdates. The object returned will contain all the same properties as your normal page object, however, this time it will contain the preview/draft content before the page has been published or saved rather than the production or saved version!

Enable inspect mode (Optional): In order to extend this code to work with the inspector, mode you will need to update it like this:

At a page level you need to create a inspectorProps object from useContentfulInspectorMode. You do this by passing in the Contentful content type ID (this is a GUID found within the CMS)! After you have the inspectorProps, function, for each property that you want to render you need to write some code to wrap that property with a call to that function, passing in the corresponding property name as the fieldId

{...inspectorProps({ fieldId: 'title' })}

Hopefully you can appreciate that code for every property will take a lot of effort!

Configure the preview settings within Contentful: With all this code set-up, the last thing is to enable the preview mode within Contentful. Log into the CMS and go to:

Settings ➜ Content Preview

Create a new preview setting, give it a name and select the content type you want to get working with live preview. After doing this, you will then need to add the URL to the preview API you created within your site earlier. In my example, the call looks like this:

http://localhost:3000/api/enable-draft-post?secret=secret&slug={entry.fields.slug}

The secret was set within the environment variable. enable-draft-post maps to the custom folder location I added my API within my code and the domain should map to your preview domain!


These are all the high-level steps you will need to follow. Setting this up took me a few days as I wanted REST and Graph to work, so expect to bump into issues. My demo site is available from GitHub, Id use that if you are struggling to play along at home. Good luck and Happy Coding 🀘