Skip to main content

Enable Live Preview

Users configuring layout using Canvas can preview their changes as they work. This requires configuration in Uniform and in the front-end application.

info

These instructions assume you already have Canvas activated in your front-end application.

Activate front-end

The activation process on the front-end depends on the technology used to build the front-end. In general, however, the process involves changing the code that reads the composition from Uniform so the most recent configuration from Uniform is used.

Nuxt.js

The Uniform Nuxt module enables Live Preview out of the box.

To access the live preview mode, just append the preview=true query string param to your composition URL. e.g. https://<your-app>/developer?preview=true

The module takes care of fetching the draft version of your composition instead of the published one.

When in preview mode, a ⚡️ emoji is prepended to the title of the page.

Next.js

In order to make these instructions easier to follow, a specific example is used. The example activates Live Preview for the following page:

Sample page used in this example
import Head from 'next/head'
import {
CanvasClient,
} from '@uniformdev/canvas'
import {
Composition,
Slot,
} from '@uniformdev/canvas-react'

export async function getStaticProps() {
const client = new CanvasClient({
apiKey: process.env.UNIFORM_API_KEY,
projectId: process.env.UNIFORM_PROJECT_ID,
})
const { composition } = await client.getCompositionBySlug({
slug: "/",
})
return {
props: {
title: 'Sample app',
message: 'Hello',
composition,
}
}
}

function UnknownComponent({ component }) {
return <div>[unknown component: {component.type}]</div>
}
function resolveRenderer({ type }) {
//TODO: Add your components.
return UnknownComponent
}

export default function Home({ title, message, composition }) {
return (
<Composition data={composition} resolveRenderer={resolveRenderer}>
<div>
<Head>
<title>{title}</title>
</Head>

<main>
<Slot name='body' />
</main>
</div>
</Composition>
)
}

Create new files

A number of new files are needed in order to support Live Preview.

  1. Add the following values to your .env file. You collected these values when you created the Uniform API key:

    {' '}

    Environment variableDescription
    UNIFORM_LIVE_PREVIEW_SECRETThis value must be included in the preview URL that you will configure in a later step.
    NEXT_PUBLIC_UNIFORM_PROJECT_IDThe value for this variable must match UNIFORM_PROJECT_ID. For more information on making environment variables available on the client, see Next.js documentation.
About this step

Technically you do not need to set the preview secret in an environment variable. You could hard-code the value into your app, but using environment variables is a "best practice".

  1. Add the following file:
lib/useLivePreviewNextStaticProps.js
import { useRouter } from 'next/router';
import { useCallback } from 'react';
import { useCompositionEventEffect } from '@uniformdev/canvas-react';

export function useLivePreviewNextStaticProps(options) {
const router = useRouter();

const effect = useCallback(() => {
router.replace(router.asPath, undefined, { scroll: false });
}, [router]);

return useCompositionEventEffect({
...options,
enabled: router.isPreview,
effect,
});
}
About this step

This creates a hook that updates props when the composition changes.

  1. Add the following page:
pages/api/preview.js
const handler = async (req, res) => {
// NOTE: in production, get this from the next config API
const previewSecret = process.env.UNIFORM_LIVE_PREVIEW_SECRET;
if (!req.query.slug) {
return res.status(400).json({ message: 'Missing slug' });
}

// raw string of the incoming slug
const slug = Array.isArray(req.query.slug) ? req.query.slug[0] : req.query.slug;

// /api/preview?disable=true&slug=/return/to/this to turn off preview mode
if (req.query.disable) {
res.clearPreviewData();
res.redirect(slug);
return;
}

if (req.query.secret !== previewSecret) {
return res.status(401).json({ message: 'Invalid token' });
}

// enable preview mode and redirect to the slug to preview
res.setPreviewData({});
res.redirect(slug);
};

export default handler;
About this step

This creates the page that displays the live preview.

Edit page files

Next you must make changes to the pages that read compositions from Uniform.

tip

This section guides you through the process of activating Live Preview by explaining each step. It takes longer to go through, but it will help you understand why each line of code is needed.

  1. In the page file, add the following code:
import Head from 'next/head'
import {
CanvasClient,
CANVAS_DRAFT_STATE,
CANVAS_PUBLISHED_STATE,
} from '@uniformdev/canvas'
import {
Composition,
Slot,
} from '@uniformdev/canvas-react'
...
  1. Add the following code:
export async function getStaticProps({ preview }) {
const client = new CanvasClient({
apiKey: process.env.UNIFORM_API_KEY,
projectId: process.env.UNIFORM_PROJECT_ID,
});
const { composition } = await client.getCompositionBySlug({
slug: '/',
state: preview ? CANVAS_DRAFT_STATE : CANVAS_PUBLISHED_STATE,
});
return {
props: {
title: 'Sample app',
message: 'Hello',
composition,
},
};
}
  1. Add the following code:
import Head from 'next/head'
import {
CanvasClient,
CANVAS_DRAFT_STATE,
CANVAS_PUBLISHED_STATE,
} from '@uniformdev/canvas'
import {
Composition,
Slot,
} from '@uniformdev/canvas-react'
import { useLivePreviewNextStaticProps } from '../lib/useLivePreviewNextStaticProps'
...
caution

Be sure to change the path to the hook to match your file's location.

  1. Add the following code:
export default function Home({ title, message, composition }) {
useLivePreviewNextStaticProps({
compositionId: composition?._id,
projectId: process.env.NEXT_PUBLIC_UNIFORM_PROJECT_ID,
});
return (
<Composition data={composition} resolveRenderer={resolveRenderer}>
<div>
<Head>
<title>{title}</title>
</Head>

<main>
<Slot name="body" />
</main>
</div>
</Composition>
);
}

Activate Uniform

  1. In Uniform, open your project.
  2. Navigate to Settings > Canvas Settings
  3. Enter the following value for Preview URL:
https://<your-app>/api/preview?secret=<your-secret>
caution

Use the hostname for your front-end app and the secret that you configured in your app.

  1. Click Save
  2. Now when you open a composition in Canvas, a button Preview is available.