Skip to main content

Live preview

Users configuring a 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. For instructions, see activation.

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 (i.e. the draft version) from Uniform is used.

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:

    Environment variableDescription
    UNIFORM_LIVE_PREVIEW_SECRET
    This can be any value you want. However, this value must be included in the preview URL that you will configure in a later step.
    NEXT_PUBLIC_UNIFORM_PROJECT_ID
    The 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".

  2. 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.

  3. 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'
    ...
  2. 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,
    }
    }
    }
  3. 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'
    ...
    important

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

  4. 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>
    )
    }
  5. Continue with the section Configure Uniform project.

Nuxt 3

The Uniform module for Nuxt enables live preview out of the box. No front-end application modifications are needed. But you still need to configure the Uniform project in order for the preview button to work.

Configure Uniform project

  1. Start your front-end application.

    can users access the application?

    If you are the only person using your Uniform project, you can run the application locally. However, if other users need to use the live preview feature, the front-end application must run somewhere that the other users can access it. This might be on a server on your network, or on an internet-accessible CDN like Netlify or Vercel.

    https and http

    You will only get the automatic update on save when your front-end application is accessed using https:// due to standard browser security.

    http:// will only work with localhost (e.g. http://localhost:3000), but this requires any user who wants to use the live preview feature to have the front-end application running locally. This is only recommended for Uniform projects where the developer is the only person using the project.

  2. In Uniform, open your project.

  3. Navigate to Settings > Canvas Settings.

  4. Enter the following value for Preview URL:

    https://[!!! APP HOST NAME !!!]/api/preview?secret=[!!! LIVE PREVIEW SECRET !!!]
    TokenValue
    [!!! APP HOST NAME !!!]
    The host name where the Next.js application is running. Any user who wants to use the live preview feature must be able to access this host from their browser.
    [!!! LIVE PREVIEW SECRET !!!]
    The value you specified for the live preview secret in the .env file.
  5. Click Save.

  6. Now when you open a composition in Canvas, a button Preview is available.