Skip to main content

Activation

This guide describes how to incorporate a Canvas composition into a front-end application.

info

The code below expects a published version of the composition be available. If the composition is only available in "preview" state, Uniform will return a null composition, which will result in errors.

For more information on composition state, see the glossary. The methods on the CanvasClient also support the ability to retrieve compositions in a specific state (i.e. not "published", which is the default value).

Create API key

  1. Click the Uniform logo at the top of the page to return to the Uniform team home page.

  2. Create an API key with the following custom permissions:

    Uniform Canvas > Compositions > Read Published
About this step

If you already have an API key with these permissions, you can skip this step.

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

    Uniform valueEnvironment variable
    API Key
    UNIFORM_API_KEY
    Project ID
    UNIFORM_PROJECT_ID
About this step

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

Update front-end app

The changes needed to the front-end depends on the technology used to build the front-end.

Next.js

In order to make these instructions easier to follow, a specific example is used. The example activates Canvas for the following page, where the presentation logic in the <main> tag will be controlled by a user with Canvas:

import Head from "next/head";

export async function getStaticProps() {
return {
props: {
title: "Sample app",
message: "Hello",
},
};
}

export default function Home({ title, message }) {
return (
<div>
<Head>
<title>{title}</title>
</Head>

<main>
<h1>{message}</h1>
</main>
</div>
);
}
tip

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

  1. Add the following packages to your app:

    @uniformdev/canvas
    @uniformdev/canvas-react
  2. Add the following code:

    import Head from 'next/head'
    import {
    CanvasClient,
    } from '@uniformdev/canvas'
    ...
  3. Add the following code:

    export async function getStaticProps() {
    const client = new CanvasClient({
    apiKey: process.env.UNIFORM_API_KEY,
    projectId: process.env.UNIFORM_PROJECT_ID,
    });
    return {
    props: {
    title: "Sample app",
    message: "Hello",
    },
    };
    }
  4. Add the following code:

    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",
    },
    };
    }
  5. Add the following code:

    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,
    },
    };
    }
  6. Add the following code:

    import Head from 'next/head'
    import {
    CanvasClient,
    } from '@uniformdev/canvas'
    import {
    UniformComposition,
    } from '@uniformdev/canvas-react';
    ...
  7. Add the following code:

    export default function Home({ title, message, composition }) {
    return (
    <div>
    <Head>
    <title>{title}</title>
    </Head>
    ...
  8. Add the following code:

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

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

    <main>
    <h1>{message}</h1>
    </main>
    </div>
    </UniformComposition>
    );
    }
  10. Add the following code:

    import Head from 'next/head'
    import {
    CanvasClient,
    } from '@uniformdev/canvas'
    import {
    UniformComposition,
    UniformSlot,
    } from '@uniformdev/canvas-react'
    ...
  11. Add the following code:

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

    <main>
    <UniformSlot name="body" />
    </main>
    </div>
    </UniformComposition>
    );
    }
    About this step

    You add the UniformSlot component in the places that match where you defined slots in your composition component.

Nuxt 3

In order to make these instructions easier to follow, a specific example is used. The example activates Canvas for the following page, where the presentation logic in the <main> tag will be controlled by a user with Canvas:

<script lang="ts" setup>
const title = 'Sample App';
const message = 'Hello';
</script>

<template>
<div>
<Head>
<Title>{{ title }}</Title>
</Head>
<main>
<h1>{{ message }}</h1>
</main>
</div>
</template>
tip

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

  1. Add the following packages to your app:

    @uniformdev/canvas
    @uniformdev/context
    @uniformdev/canvas-vue
    @uniformdev/context-vue
    @uniformdev/uniform-nuxt
  2. Add the Nuxt module to nuxt.config.ts:

    export default defineNuxtConfig({
    modules: ["@uniformdev/uniform-nuxt"],
    uniform: {
    projectId: process.env.UNIFORM_PROJECT_ID,
    readOnlyApiKey: process.env.UNIFORM_API_KEY,
    },
    });
  3. Update the page's script to use useUniformComposition (it's auto-imported by the module):

    <script lang="ts" setup>
    const title = "Sample App";
    const { composition } = await useUniformComposition({ slug: "/" });
    </script>
  4. Update the template to use <UniformComposition> and <UniformSlot> to render the composition (they are both auto-imported by the module):

    <template>
    <UniformComposition :data="composition">
    <div>
    <Head>
    <Title>{{ title }}</Title>
    </Head>
    <main>
    <UniformSlot name="body" />
    </main>
    </div>
    </UniformComposition>
    </template>
  5. Now we should tell <UniformComposition> how to render each Uniform component. To do so, we will use our generic component renderer DefaultNotImplementedComponent, but you can update the resolveRenderer function to use any Vue components you want based on the Uniform component type.

     <script lang="ts" setup>
    import { DefaultNotImplementedComponent } from '@uniformdev/canvas-vue';

    const resolveRenderer = ({ type }) => {
    // TODO: extend the function to return a component based on the `type` property.
    return DefaultNotImplementedComponent;
    };
    const title = 'Sample App';
    const { composition } = await useUniformComposition({ slug: '/' });
    </script>

    <template>
    <UniformComposition :data="composition" :resolve-renderer="resolveRenderer">
    <div>
    <Head>
    <Title>{{ title }}</Title>
    </Head>
    <main>
    <Slot name="body" />
    </main>
    </div>
    </UniformComposition>
    </template>