Nuxt tutorial

warning

The tutorial is being updated at the moment. This version is slightly behind the latest Uniform capabilities.

This tutorial will guide you through the process of building a web application that uses Uniform's composition capabilities:

  • Build a web application using your preferred front-end framework.
  • Enable layout to be controlled by non-developers.

This is a very basic web app by design. This will allow you to focus on the Uniform bits instead of getting caught up with styles, design or complicated application functionality.

tip

You must have the following available to complete this tutorial:

goals

In Uniform, most of the settings that control layout for your web application are set and stored in a project. To configure these things, you need a project. This involves the following:

  • Understand what a Uniform project is.
  • Create a new Uniform project using the Uniform dashboard.
  • Understand what a Uniform API key is.
  • Create a new Uniform API key.

Projects are created and configured using the Uniform dashboard.

  1. Log into the Uniform dashboard at https://uniform.app.
  2. Create the following project:
    • Project name: Intro to Canvas Tutorial
  3. The project dashboard page is displayed.

Your web application will need to read data and settings from the Uniform project. This requires a valid API key be assigned to the project, and for the right permissions assigned to the key. Learn more about roles and permissions.

  1. From the Uniform team home page, navigate to Security > API Keys.

  2. Add the following API key:

    • Name: Intro to Canvas Tutorial key
    • Project: Intro to Canvas Tutorial
  3. In the row for your Intro to Canvas Tutorial project, select the "..." to open custom permissions and select:

    Compositions > Read Draft Compositions > Read Published
  4. Click Use Custom Permissions.

  5. Click Create API Key.

  6. Three values are displayed, but we're only working with two: the API key and the project ID. Copy both of these values. You will need them later.

warning

This is the only time the API key will be displayed. If you lose the value you will need to create a new one.

goals

To incorporate Uniform into your web application, you need a development environment. This involves the following:

  • Add the web application for the tutorial to your development environment.
  • Add your Uniform API key to the web application.
  • Run the web application in dev mode.

You can complete this tutorial using whatever development environment you prefer. We find that most people work best on a local work station.

  1. Enter the following commands:

    git clone https://github.com/uniformdev/examples cd examples cd examples/docs/intro-to-canvas/nuxtjs/no-uniform
  2. Open the file .env.

  3. Set the environment variables to match the values you collected during project setup.

    UNIFORM_API_KEY=[!!! YOUR API KEY !!!] UNIFORM_PROJECT_ID=[!!! YOUR PROJECT ID !!!]
  4. Save the file.

  5. Open a terminal in the root of the repository.

  6. Run the following commands:

    cd examples/docs/intro-to-canvas/nuxtjs/no-uniform npm install npm run dev
  7. Open your browser to the following URL:

    http://localhost:3000

goals

Uniform enables you to define the layout for a digital experience (like a web page, email message or screen in a mobile app), using a no-code tool. This involves the following:

  • Understanding the basic Uniform terminology related to layout management.
  • Defining components that represent the layout.
  • Creating a composition that lets you specify the components that make up a web page.

Once the Uniform application is configured, business users can add data and content to experiences using a no-code tool called Uniform Canvas. Uniform compositions leverage components, which represent anything that's displayed by the front-end. Users specify which components to use and the conditions under which those components are used. Variation options include A/B testing, classification, and personalization.

what's Uniform Canvas?

Uniform Canvas lets business users control layout without having to get into front-end design. You can think of Canvas as "layout as a service." The business user can control which components are used and what content is available to those components, but leaves the responsibility for how those components are built in the hands of the front-end developer.

What you create in Canvas is a representation of the application components that business users can interact with. As you will see later, the name of the component gets mapped to the implementation of the component that's built by a front-end developer.

Components need only be defined in the app for content or data that business users should be able to control. For example, there is nothing in the navigation or footer components in this tutorial for the business user to control, so components don't need be created for them.

This tutorial includes a component type called "Default Body." This component type is represents most of the content that will make up a web page. It includes everything present within the 'main' tag in the Body.jsx file in the code base.

A business user will be able to personalize this component by specifying different content depending on whether the visitor has viewed the Architecture page.

  1. In your Uniform project, navigate to Canvas > Component Library.

  2. Click the red (+) button.

  3. Enter the following values:

    Component Name: Default Body Component Icon: menu-boxed
  4. Click Parameters.

    info

    Parameters allow business users to set values that are passed to the component. They give the user the ability to control the component, but within the limits specified by the parameter settings.

  5. Click the red (+) button.

  6. Enter the following values:

    • Parameter Name: Content ID
    • Public ID: contentId
    • Type: Text
    • Required: ticked

    info

    When a business user adds this component to a composition, they will be required to set a value for this parameter.

  7. Click OK.

  8. Click Save and close.

Now we will create another component type which will represent an element that a business user can use to create experiences: a composition component. In this tutorial, this component represents a page on the site that a business user can add a Default Body component to.

  1. In your Uniform project, navigate to Canvas > Compositions. Click the red (+) button.

  2. Enter the following values:

    • Component Name: Default Page
    • Component Icon: file-document
    • Composition Component: ticked

    info

    This component is marked a composition component because you want a business user to be able to create a composition based on it.

  3. Click Slots.

    info

    Slots represent areas in which components can be placed. Uniform determines which component to insert into a slot based on configurations set by the business user.

  4. Click the red (+) button.

  5. Enter the following values:

    • Slot Name: body
    • Minimum: 1
    • Maximum: 1
    • Allowed Components: Default Body

    info

    These settings ensure that:

    • At least 1 component is entered into the slot
    • No more than 1 component is entered into the slot
    • The only component type that's entered is the Default Body
  6. Click OK.

  7. Click Save and close.

Now you need to create a composition that represents the home page.

  1. Click Compositions in the list on the left.

  2. Click the red (+) button.

  3. Enter the following values:

    • Select a composition type: Default Page
    • Name: Home Page
  4. Click Create.

  5. For the Slug, enter /

    info

    The slug is the value the front-end logic will use to retrieve the details about the composition. Don't be confused by the value being /. The value could just as easily have been "home" or "home page." As long as the front-end logic uses the same value, the slug can be whatever you want.

  6. Click the green (+) button in the body slot to add a component.

  7. Click Default Body.

  8. Enter the following values:

    • Content ID: home
  9. The Save button also acts as a drop-down. Click the ⌵ icon to activate the dropdown.

  10. Click Save > Save and publish.

  11. Click < Compositions in the upper left-hand corner.

goals

You have configured the instructions that control composition. Next you need to update the web app to execute those instructions. This involves the following:

  • Understanding how the configuration from Canvas is used in a web app.
  • Updating a web application so that a layout is read from Canvas.

You configured a composition that defines layout instructions for the home page. The next step is to update the front-end application so it uses those layout instructions.

  1. Open a terminal in the root of the repository.

  2. Enter the following commands:

    cd examples/docs/intro-to-canvas/nuxtjs/no-uniform npm install @uniformdev/canvas @uniformdev/context @uniformdev/canvas-vue @uniformdev/context-vue @uniformdev/uniform-nuxt

    warning

    If you get an error while installing these packages you might need to add the --legacy-peer-deps switch to the end of the command above.

About this step

This adds references to the packages for Nuxt 3 apps that need to use Canvas.

When you created your composition and added a component to the Body slot in the last step, you specified a content id for the component. That content ID is stored by Uniform, and the front-end application must retrieve the details for the item. To simplify that process, Uniform provides an "enhancer" API that calls the data source to fetch those details and collect them into a single object for use by front-end developers.

Add the following file to the root of your application:

/lib/enhancer.js

import { enhance, EnhancerBuilder } from "@uniformdev/canvas"; import content from "../content/content.json"; // Uses the parameter value from the composition // to look up the topic from the data file. If // the topic is found, the fields are returned. const dataEnhancer = async ({ component }) => { const contentId = component?.parameters?.contentId?.value; if (contentId) { const topic = content.find((e) => e.id == contentId); if (topic) { return { ...topic.fields }; } } }; export default async function doEnhance(composition) { const enhancedComposition = { ...composition }; const enhancers = new EnhancerBuilder().data("fields", dataEnhancer); await enhance({ composition: enhancedComposition, enhancers, }); return enhancedComposition; }

A component resolver is needed to map the Uniform component name to React components. This means you must add the mapping to you front-end application.

Add the following file:

/lib/resolveRenderer.js

import Body from "../components/Body.vue"; import { DefaultNotImplementedComponent } from "@uniformdev/canvas-vue"; export default function resolveRenderer({ type }) { if (type == "defaultBody") { return Body; } return DefaultNotImplementedComponent; }

Add the following file:

/src/components/LayoutCanvas.vue

<script lang="ts" setup> import Footer from "./Footer.vue"; defineProps<{ title: string }>(); </script> <template> <div class="container"> <Head> <Title>{{ title }}</Title> <link rel="icon" href="/favicon.ico" /> </Head> <UniformSlot name="body" /> <Footer /> </div> </template>

Adding Canvas to the home page involves making changes to the front-end application. Follow the steps that match your front-end technology.

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. Edit the following file:

    /nuxt.config.ts

    import { defineNuxtConfig } from "nuxt"; // https://v3.nuxtjs.org/api/configuration/nuxt.config export default defineNuxtConfig({ css: ["~/styles/globals.css", "~/styles/page.css"], modules: ["@uniformdev/uniform-nuxt"], });

    About this step

    This adds the Uniform module, which brings Uniform functionality to Nuxt.

  2. Edit the following file:

    /nuxt.config.ts

    import { defineNuxtConfig } from "nuxt"; // https://v3.nuxtjs.org/api/configuration/nuxt.config export default defineNuxtConfig({ css: ["~/styles/globals.css", "~/styles/page.css"], modules: ["@uniformdev/uniform-nuxt"], uniform: { projectId: process.env.UNIFORM_PROJECT_ID, readOnlyApiKey: process.env.UNIFORM_API_KEY, apiHost: process.env.UNIFORM_CLI_BASE_URL, }, });

    About this step

    This sets the values the Uniform modules uses to connect to Uniform. You set the project ID and API key values as environment variables in a previous step. The API host value is optional, and is used when you want to use an alternate endpoint for the Uniform API.

  3. Edit the following file:

    /nuxt.config.ts

    import { defineNuxtConfig } from "nuxt"; import { ManifestV2 } from "@uniformdev/context"; // https://v3.nuxtjs.org/api/configuration/nuxt.config export default defineNuxtConfig({ css: ["~/styles/globals.css", "~/styles/page.css"], modules: ["@uniformdev/uniform-nuxt"], uniform: { projectId: process.env.UNIFORM_PROJECT_ID, readOnlyApiKey: process.env.UNIFORM_API_KEY, apiHost: process.env.UNIFORM_CLI_BASE_URL, manifest: {} as ManifestV2, }, });

    About this step

    The Nuxt module for Uniform requires a manifest be set to pass validation checks within the Nuxt module. This sets a manifest to meet this requirement.

  4. Edit the following file:

    /nuxt.config.ts

    import { defineNuxtConfig } from "nuxt"; import { ManifestV2 } from "@uniformdev/context"; // https://v3.nuxtjs.org/api/configuration/nuxt.config export default defineNuxtConfig({ css: ["~/styles/globals.css", "~/styles/page.css"], modules: ["@uniformdev/uniform-nuxt"], uniform: { projectId: process.env.UNIFORM_PROJECT_ID, readOnlyApiKey: process.env.UNIFORM_API_KEY, apiHost: process.env.UNIFORM_CLI_BASE_URL, manifest: {} as ManifestV2, defaultConsent: true, }, });

    About this step

    The Nuxt module for Uniform requires a manifest be set to pass validation checks within the Nuxt module. This sets a manifest to meet this requirement.

  5. Edit the following file:

    /pages/index.vue

    <script lang="ts" setup> import content from "../content/content.json"; const slug = "/"; const topic = content.find((e) => e.url == slug); const { composition } = await useUniformComposition({ slug }); </script> <template> <Layout :content="content" :fields="topic.fields" /> </template>

    About this step

    This uses the Uniform module to retrieve the composition using the specified slug.

  6. Edit the following file:

    /pages/index.vue

    <script lang="ts" setup> import content from "../content/content.json"; import doEnhance from "../lib/enhancer"; const slug = "/"; const topic = content.find((e) => e.url == slug); const { composition } = await useUniformComposition({ slug, enhance: async (c) => await doEnhance(c) }); </script> <template> <Layout :content="content" :fields="topic.fields" /> </template>

    About this step

    This applies the enhancer to the composition.

  7. Edit the following file:

    /pages/index.vue

    <script lang="ts" setup> import content from "../content/content.json"; import doEnhance from "../lib/enhancer"; import resolveRenderer from "../lib/resolveRenderer"; const slug = "/"; const topic = content.find((e) => e.url == slug); const { composition } = await useUniformComposition({ slug, enhance: async (c) => await doEnhance(c) }); </script> <template> <UniformComposition v-if="composition" :data="composition" :resolve-renderer="resolveRenderer" > <Layout :content="content" :fields="topic.fields" /> </UniformComposition> </template>

    About this step

    In Canvas you added a component to a slot in a composition. The front-end application must determine which front-end component to use to render the Canvas component. The component you add in this step makes this decision.

  8. Edit the following file:

    /pages/index.vue

    <script lang="ts" setup> import content from "../content/content.json"; import doEnhance from "../lib/enhancer"; import resolveRenderer from "../lib/resolveRenderer"; import LayoutCanvas from "../components/LayoutCanvas.vue"; const slug = "/"; const topic = content.find((e) => e.url == slug); const { composition } = await useUniformComposition({ slug, enhance: async (c) => await doEnhance(c) }); </script> <template> <UniformComposition v-if="composition" :data="composition" :resolve-renderer="resolveRenderer" > <LayoutCanvas :title="topic.fields.title" /> </UniformComposition> </template>

    About this step

    This adds the layout component you created earlier.