Live preview
Table of contents
What is live preview
Live preview allows users to preview their content in real time in the same page with the entry editor. As changes to the content are made, they are immediately reflected in the preview pane.
Live preview enables the following capabilities for you:
- Side-by-side previewing and editing — Edit your entry and preview changes in the same web app page, no switching between the tabs is needed:
- Live updates — As you edit your entry, the changes are simultaneously displayed in the preview pane, without refreshing the preview:
- Inspector mode — Click Edit against a specific piece of website content to quickly jump to its source field and make the necessary changes:
How live preview works
When content is changed, the entry editor sends an event that includes the updated content to the live preview SDK. This event triggers an update to your preview website. The live preview SDK is responsible for processing the updated content and rendering it correctly in the preview frontend. This processing supports both the REST and GraphQL APIs of the Content preview API (CPA). As part of the live preview setup, you embed an SDK script in your website’s code. When a user opens the live preview pane in the entry editor, your preview website is launched in an iframe using the SDK.
Set up live preview
Setting up live preview involves the following main stages:
1. Configure Content preview
As a prerequisite for setting up and using live preview, you must configure the preview URL and add it to your Content preview. To learn how to set it up, refer to Content preview.
2. Initialise live preview SDK
To establish communication between your preview website and Contentful, you need to initialize the live preview SDK. The process differs slightly depending on whether you are using a framework like React.js or just vanilla JavaScript.
For Vanilla JavaScript:
import { ContentfulLivePreview } from '@contentful/live-preview';
ContentfulLivePreview.init({ locale: 'en-US' });
For React.js applications:
You must initialize the live preview SDK with the live preview provider. This provider accepts the same arguments as the init
function:
import { ContentfulLivePreviewProvider } from '@contentful/live-preview/react';
const App = ({ Component, pageProps }) => (
<ContentfulLivePreviewProvider locale="en-US">
<Component {...pageProps}>
</ContentfulLivePreviewProvider>
)
Init configuration
The init
function accepts a configuration object that allows you to customize your live preview SDK experience. The following options are available:
import { ContentfulLivePreview } from '@contentful/live-preview';
ContentfulLivePreview.init({
locale: 'set-your-locale-here' // Required: allows you to set the locale once and have it reused throughout the preview.
enableInspectorMode: false, // Optional: allows you to toggle inspector mode which is on by default.
enableLiveUpdates: false, // Optional: allows you to toggle live updates which are on by default.
debugMode: false,// Optional: allows you to toggle debug mode which is off by default.
});
To optimize non-preview websites, it is advisable to disable live preview functionality by setting both enableInspectorMode
and enableLiveUpdates
to "false". By doing so, any specific data related to live preview, such as data-attributes, is removed.
3. Optional: Set up live updates
Live updates allow you to preview your changes without clicking the "Refresh preview" button. Whenever content is updated, the changes are immediately displayed in the live preview pane.
Live updates are natively supported for Vanilla JS and React.js applications. The updates are only happening on the client-side and in live preview.
To set up live updates with React.js, import the useContentfulLiveUpdates
hook and pass the original data to it. The hook then returns the live updated data in real time. See an example in the code snippet below:
sys.id
and __typename
in your query.
import { useContentfulLiveUpdates } from '@contentful/live-preview/react';
const updatedEntries = useContentfulLiveUpdates(entries);
4. Optional: Set up inspector mode
Inspector mode allows users to locate a field that contains a specific piece of website content with a single click. When you click "Edit" button beside a content block in the preview iframe, you are redirected to the corresponding field within the entry. If the field contains reference to another entry, you are redirected to the referenced entry editor.
To enable inspector mode, tag the corresponding field(s). To tag a field, specify its location within the entry by writing data attributes. The live preview SDK scans for these elements containing the correct field tags.
The required data attributes can be added according to one of the following options:
- Adding the data attributes directly into your code:
data-contentful-field-id
data-contentful-entry-id
- Running the helper function from the live preview SDK:
import { ContentfulLivePreview } from '@contentful/live-preview';
<h1 {...ContentfulLivePreview.getProps({ entryId: id, fieldId: 'title' })}>
{title}
</h1>;
To include the necessary styles for inspector mode in your main index.js file using npm, use the following syntax:
import '@contentful/live-preview/style.css';
Inspector mode best practices
We recommend to tag fields as follows:
Tag larger elements — Only tag elements of the page that are significantly larger than the mouse cursor. Tagging smaller elements such as icons inside buttons can result in a very fragmented tagging surface and we recommend to rather only tag the button itself then.
Nested entries — Don't tag pages further than 3 nesting levels. We believe that there is a tipping point where additional tagging of nested entries is not beneficial for the user experience since moving the mouse slightly will potentially show you various "Edit" buttons of different content pieces.
References — Tag the whole referenced entry and the main content inside for faster editing. In case where the text inside is short - for example, the reference is a circle with a one-word text inside — then the recommendation is to refrain from tagging this text.
Website sections — We definitely recommend tagging the sections of a page.
Styling — Many customers manage styling parameters with Contentful, e.g. the background color for a section or the margins around texts. We generally don’t recommend tagging styling as it might result in a confusing user experience, as hover areas intersect to a large extent or fully with the element the styling applies to.
Known issues and limitations
Limitations with live updates and GraphQL:
- GraphQL filters (e.g. filters in the Array field type).
- GraphQL aliasing (renaming the data that is returned from a query is not supported).
- Multiple locales in one GraphQL query.
I configured the preview URL, but I only see “Refused to connect”
This can happen if your website has a strict security configuration (Security Header or Content Security Policy (CSP)), which prevents other websites from embedding it. Reach out to your dev or security team to modify your website security configuration for enabling live preview support. To view whether your website security configuration allows live preview support, perform the following steps:
Go to the Network tab of your browser console.
Search for the required page.
Under the Headers subtab, go to the Response Headers.
Check whether the security configuration is set according to one of the following options:
- the X-Frame-Options header — If the X-Frame-Options header is set, remove it.
OR
- Content-Security-Policy header must include
frame-ancestors https://app.contentful.com
My page has an authorization cookie for logging in
To have functional or accessible cookies inside the live preview iframe, configure them with SameSite=None
and the Secure
flag. This allows your browser to pass them to the iframe.
For example, you want users to log in to the preview website with an authorization cookie. In this case, the cookie is set up as follows:
Set-Cookie: auth=abc123; SameSite=None; Secure