Skip to main content

Install Live Preview

Install Live Preview so your stack can read content through Contentstack's preview API, which is where drafts come from. It's two changes to your app: a live_preview block on the stack you already have, and a call to ContentstackLivePreview.init in the browser. The Studio canvas uses the first one.

The example on this page is the Blog stack, in North America, and the Next.js App Router app whose stack is in lib/contentstack.ts. The canvas shows the Blog post template, previewing AI 101.

Prerequisites​

  • The Delivery SDK stack in lib/contentstack.ts. The live_preview block goes on that same contentstack.stack call. See Install the Delivery SDK.
  • A preview token. It's a different value from the delivery token. See What you need in your stack.
  • Your region's preview host. It's a different address from the delivery host.
  • Whether your templates render on the client or on the server, because the browser setup differs. See CSR or SSR.

What Live Preview does for Studio​

The live_preview block points your stack at Contentstack's preview API, which is a different service from the delivery API. Inside Studio's canvas, the Studio SDK reads the preview hash from the canvas URL and passes it to your stack's livePreviewQuery.

Live Preview Utils, the package @contentstack/live-preview-utils, is a separate part. The Studio SDK doesn't use it, and never calls ContentstackLivePreview.

Faster ways to do this​

  • Skill, for the full install. Ask your agent to install Studio, and it uses install-studio. It sets up Live Preview along with the Delivery SDK and the Studio SDK. It wraps Live Preview so a Live Preview failure can't stop the Studio SDK starting.
  • Skill, for an app that has the Delivery SDK already. Ask your agent to add Live Preview, and it uses install-live-preview. It reads the stack's Live Preview setting before it changes anything.

See What are skills? No CLI command installs Live Preview.

Install Live Preview Utils​

npm install @contentstack/live-preview-utils

With Yarn or pnpm, run yarn add or pnpm add with the same package name.

Add the live_preview block to your stack​

  1. Add the preview token to your environment file:

    NEXT_PUBLIC_CONTENTSTACK_PREVIEW_TOKEN=your_preview_token

    Read the preview token from an environment variable, and never commit it.

  2. In lib/contentstack.ts, add live_preview to the contentstack.stack call:

    import contentstack from "@contentstack/delivery-sdk";

    export const stack = contentstack.stack({
    apiKey: process.env.NEXT_PUBLIC_CONTENTSTACK_API_KEY!,
    deliveryToken: process.env.NEXT_PUBLIC_CONTENTSTACK_DELIVERY_TOKEN!,
    environment: process.env.NEXT_PUBLIC_CONTENTSTACK_ENVIRONMENT!,
    live_preview: {
    enable: true,
    // Read the token from the environment. Never commit it.
    preview_token: process.env.NEXT_PUBLIC_CONTENTSTACK_PREVIEW_TOKEN!,
    // The preview API, which is a different address from the delivery one.
    host: "rest-preview.contentstack.com",
    },
    });
  3. Set host to your region's preview host. The example uses rest-preview.contentstack.com, the North America host. It doesn't work for a stack in another region, so use the host that Contentstack's regions docs list for yours. Don't set it to your delivery host, because drafts come from a different service.

If your app calls livePreviewQuery on this stack anywhere else, give the Studio SDK its own stack instance, built from the same credentials. Studio calls livePreviewQuery on the stack you pass it, so both would share its state.

Start Live Preview in the browser​

Call ContentstackLivePreview.init once, in the browser, before any route renders. Calling it twice breaks Live Preview. Wrap it in try and catch, so an error there doesn't stop the studioSdk.init call below it from running.

import ContentstackLivePreview, { IStackSdk } from "@contentstack/live-preview-utils";
import { stack } from "@/lib/contentstack";

try {
ContentstackLivePreview.init({
// Turn Live Preview on.
enable: true,
// false: your app refetches on onEntryChange. true: Contentstack reloads the page.
ssr: false,
// "builder" for Visual Editor. "preview" for the Live Preview panel only.
mode: "builder",
// The config of the stack in lib/contentstack.ts, with its live_preview block.
stackSdk: stack.config as IStackSdk,
stackDetails: {
apiKey: process.env.NEXT_PUBLIC_CONTENTSTACK_API_KEY!,
environment: process.env.NEXT_PUBLIC_CONTENTSTACK_ENVIRONMENT!,
},
// The Contentstack app for your region. This is North America.
clientUrlParams: {
host: "app.contentstack.com",
},
// Show the Edit button on your site inside Live Preview.
editButton: {
enable: true,
},
});
} catch (err) {
console.warn("Live Preview init failed. Continuing without it.", err);
}

What each option does:

OptionWhat it doesIn the example
enableTurns Live Preview on. Set it to false to turn it off without removing the call.true
ssrHow your page updates when an author edits an entry. With false, Live Preview fires onEntryChange and your app refetches. With true, Contentstack reloads the whole page with the new preview hash in the URL, and onEntryChange doesn't fire. Defaults to true.false, because the Blog app refetches in onEntryChange
mode"builder" turns on Visual Editor, which needs your page to carry data-cslp tags. "preview" is the Live Preview panel only. Defaults to "preview"."builder"
stackSdkThe config of your Delivery SDK stack, stack.config. Live Preview writes the preview hash into it, so your stack's next fetch returns drafts. You need it when ssr is false.stack.config from lib/contentstack.ts
stackDetailsYour stack's API key and environment. Visual Editor uses them to open the right entry.The Blog stack's API key, and the environment from NEXT_PUBLIC_CONTENTSTACK_ENVIRONMENT
clientUrlParams.hostThe address of the Contentstack app that opens your site. Defaults to app.contentstack.com, the North America app. For a stack in another region, use that region's app address, such as eu-app.contentstack.com.app.contentstack.com
editButton.enableShows the Edit button on your site when it opens inside Live Preview. Defaults to true.true

ContentstackLivePreview.init is Contentstack's API. These are the options this setup needs. For every option, see Contentstack's Live Preview Utils docs, for the version you install.

On a server-rendered route, Studio needs one more thing from you. It reads the preview hash from the searchQuery you pass to fetchCompositionData, from its hash or live_preview parameter, and passes it to your stack's livePreviewQuery. Studio only calls livePreviewQuery when the request carries a hash, so otherwise your stack keeps its own Live Preview setup. See Render on the server.

To make a template refetch when an author saves an entry, wire onEntryChange. See Refresh the template when an entry changes on the client, or Render on the server.

Check the preview token is set​

Log the preview token that lib/contentstack.ts reads, once, and check it isn't undefined. Remove the log when you're done.

console.log(process.env.NEXT_PUBLIC_CONTENTSTACK_PREVIEW_TOKEN);

The check that the canvas shows a draft waits until the canvas route is mounted. It's in Check a section on the canvas.

Next, install the Studio SDK in the same module: Install the Studio SDK.

If it doesn't work​

The delivery token is in preview_token​

The preview token and the delivery token are different values. Put the preview token in preview_token. See What you need in your stack.

The preview host is the delivery host​

Drafts come from the preview API, which is a different address from the delivery API. Set live_preview.host to your region's preview host, not the host you set on the stack.

The preview host is for another region​

The North America preview host, rest-preview.contentstack.com, doesn't work for a stack in another region. Use the preview host that Contentstack's regions docs list for your region.

The preview token is undefined at runtime​

The variable has the wrong prefix for your framework, or the dev server started before you added it. See A value is undefined at runtime.

The Studio SDK doesn't start after you add Live Preview​

An error in ContentstackLivePreview.init stops the code after it, including studioSdk.init. Wrap the call in try and catch, as in Start Live Preview in the browser. Check, too, that your app calls it only once.

Your own livePreviewQuery calls clash with Studio's​

Studio calls livePreviewQuery on the stack you pass it, so your calls and Studio's share that stack's state. Build a second stack from the same credentials, and pass that one to the Studio SDK.

Report a problem with this page