Skip to main content

v6.x

This section provides guides on how to use Uniform with Sitecore XM/XP. The information in this section applies to the v6.x version of the Unifom connector.

This is not the latest version

For documentation on the latest version of the Sitecore connector, see Sitecore XM/XP.

This section describes how to modernize the default Sitecore site. When you are done you will have the Sitecore site running with the following configuration:

  • Content managed in Sitecore
  • Layout & renderings ported to React components
  • CSS ported to front-end
  • Front-end managed by Next.js
  • Presentation details managed in Uniform Canvas

Prerequisites

  • Uniform account (free tier or greater)
  • Node.js installed on your machine (version 14 or greater)
  • Sitecore instance (8.2, 9.0.2 or greater)
  • Sitecore admin user login (e.g. sitecore\admin)
  • Uniform connector is installed on your Sitecore instance. If it is not already installed you should install it now.
  • Uniform API token from Sitecore instance.
  • Npm access token (contact Uniform Product Support if you need one).
info

Communication between the Uniform app and Sitecore is done entirely client-side using cross-domain requests. This means the Sitecore instance must be accessible using https://. This also means the Sitecore instance can be a local instance.

Configure Sitecore Services Client

Configure Sitecore Services Client for Sitecore 8.2

Uniform uses the Sitecore Services Client (SSC) to read content from Sitecore, so SSC must be enabled and configured.

  1. If SSC is not enabled, you must enable it. The following is an example of a config file that enables SSC:
    <configuration>
    <sitecore>
    <settings>
    <setting name="Sitecore.Services.AllowAnonymousUser" value="true" />
    <setting name="Sitecore.Services.AllowItemServiceAnonymousUser" value="true" />
    <setting name="Sitecore.Services.SecurityPolicy" value="Sitecore.Services.Infrastructure.Web.Http.Security.ServicesOnPolicy, Sitecore.Services.Infrastructure" />
    </settings>
    </sitecore>
    </configuration>
  2. In Website folder, open Web.config and config CORS header
    <system.webServer>
    <httpProtocol>
    <customHeaders>
    <remove name="X-Powered-By" />
    <add name="Access-Control-Allow-Origin" value="https://uniform.app" />
    </customHeaders>
    </httpProtocol>
    </system.webServer>
  3. Grant sitecore\servicesAPI user with access to site items, /sitecore/system/Languages, /sitecore/templates and /sitecore/system/Uniform
tip

We also recommend that the user sitecore\servicesAPI have permissions configured that explicitly deny access to the remaining parts of the content tree. This is the account SSC uses by default for calls.

Configure Sitecore Services Client for Sitecore 9.0.2 or greater

Uniform uses the Sitecore Services Client (SSC) to read content from Sitecore, so SSC must be enabled and configured.

  1. If SSC is not enabled, you must enable it. The following is an example of a config file that enables SSC:
    <configuration>
    <sitecore>
    <settings>
    <setting name="Sitecore.Services.AllowAnonymousUser" value="true" />
    <setting name="Sitecore.Services.AllowItemServiceAnonymousUser" value="true" />
    <setting name="Sitecore.Services.SecurityPolicy" value="Sitecore.Services.Infrastructure.Web.Http.Security.ServicesOnPolicy, Sitecore.Services.Infrastructure" />
    </settings>
    </sitecore>
    </configuration>
  2. In Sitecore, open Content Editor.
  3. Navigate to sitecore > system > Settings > Services > API Keys.
  4. Add the following item:
    • Template: API Key
    • Name: Uniform API Key
  5. Set the following field values:
    • CORS Origins: https://uniform.app
    • Allowed Controllers: Sitecore.Services.Infrastructure.*
    • Impersonation User: Name of a Sitecore user with access to site items, /sitecore/system/Languages, /sitecore/templates and /sitecore/system/Uniform (for example, sitecore\admin)
  6. Save the item.
  7. Publish the item.
  8. Note the item ID. This is your Sitecore API key. You will need this value later.
tip

We also recommend that the user sitecore\servicesAPI have permissions configured that explicitly deny access to the remaining parts of content tree. This is the account SSC uses by default for calls when an API key is not specified.

Create Uniform project

A Uniform project is where all of the settings related to your web app are configured. You must create a new project for your web app.

  1. Log into https://uniform.app.
  2. Click (+) to create a new project.
  3. Enter the following values and click Continue.
    • Project name: My Site Project

Create Uniform API key

A Uniform API key is needed for both Sitecore and the web app to communicate with Canvas. You must create a new key for your web app

  1. In Uniform, click the logo in the top-left to return to the home page.
  2. Navigate to Settings > API Keys.
  3. Click (+).
  4. Enter the following values:
    • Name: My Site key
    • Project dropdown: My Site Project
  5. Select the following permissions in the section Uniform Canvas:
    • Component Library > Manage
    • Compositions > Read Draft
    • Compositions > Read Published
  6. Click Create API Key.
  7. Note the value for Key because this is the only time it will be displayed. This is your Uniform API key.
  8. Note the value for the project My Site Project. This is your Uniform project ID.
  9. Click Close.

Configure Sitecore site

Canvas will read content from your Sitecore site, but some configuration is needed. This configuration comes in the form of something called site configuration. The Uniform connector on your Sitecore instance uses the site configuration to determine which Uniform functionality to enable. You must create a site configuration for your web app.

tip

Site configuration can be created using Sitecore config files or Sitecore items. These instructions use Sitecore items. The config file approach is recommended for production environments, but using Sitecore items may be easier for some users during development and testing.

  1. In Content Editor, navigate to sitecore > system > Uniform > SiteConfigurations.
  2. Add the following item:
    • Template: Site Configuration
    • Name: MySite
  3. Add an item using the template Configure Site.
  4. Select the child item Configuration.
  5. Set the following field values:
    • Inherits: website
  6. Save the item.
  7. Publish the site.
info

Before the Canvas-specific settings can be configured, some other steps must be completed. You will return to the site configuration later.

Add Sitecore integration to Uniform project

In order for Canvas to be able to read content from Sitecore, you must add and configure an integration in your Uniform project.

  1. In Uniform, click the logo in the top-left to return to the home page.
  2. Navigate to the project My Site Project.
  3. Navigate to the Integrations tab.
  4. Click Sitecore.
  5. Click Add to project.
  6. In the Sitecore configuration screen, enter the following values:
    • URL of your Sitecore instance: The URL to the root of the Sitecore instance. This must start with https://.
    • Sitecore API key: Your Sitecore API key or any GUID if you use Sitecore 8.2
    • Site configuration name: MySite
  7. Click Save.
  8. A message will appear to indicate that values were stored. If you see an error message, consider the following troubleshooting steps:
    • Verify that SSC is configured correctly using /sitecore/admin/showconfig.aspx on your Sitecore instance.
    • Verify that the user account defined in Sitecore API key has read access rights to the item /sitecore/system/Uniform/Site Configurations/MySite.
    • Check your browser's dev console for client-side error messages.
    • Consult with Sitecore SSC documentation.
    • Contact Sitecore support regarding SSC connectivity issues.

Replicate Sitecore layout in Canvas

You need to model the home page from the Sitecore site in Canvas. This involves porting the layout, renderings and presentation details from Sitecore into Canvas.

To get to the presentation:

  1. In Content Editor, navigate to sitecore > Content > Home.
  2. In the ribbon, click PRESENTATION.
  3. In the toolbar, click Details.
  4. In the Layout Details screen, in the section for the default device, click Sample Layout.
  5. In the Device Editor screen, click the tab Controls.

If you look at the presentation details assigned to the home item, you will see three controls. These controls represent a fairly complex sort of layout with nested placeholders. This makes this item a good example to use.

https://d33wubrfki0l68.cloudfront.net/46f4683a8c0a496e45c000ff499c85ad289184ac/7ce7c/img/integrations/content/sitecore/v6/sitecore1.png

  • The layout has a rendering Sample Sublayout assigned to the placeholder main.
  • The rendering Sample Sublayout has a placeholder centercolumn with a rendering Sample Inner Sublayout assigned to it.
  • The rendering Sample Inner Sublayout has a placeholder content with a rendering Sample Rendering assigned to it.
  • The rendering Sample Rendering either does not have any placeholders or it has placeholders but no renderings have been assigned to any of them yet.

This is the structure you will replicate in Canvas.

Component: Sample Layout

You must define a Canvas component that represents the Sample Layout from Sitecore.

  1. In Uniform, click the logo in the top-left to return to the home page.
  2. Navigate to the project My Site Project.
  3. Navigate to Canvas > Component Library.
  4. Click (+).
  5. In the Add Component Type screen, enter the following values:
    • Component Name: Sample Layout
    • Composition Component: ticked
  6. Navigate to Slots.
  7. Click (+).
  8. In the Add Slot screen, enter the following values:
    • Slot Name: main
  9. Click OK.
  10. Click Save and close.
info

By default, when you add a new slot, Uniform generates a Public ID value based on the Slot Name. The Public ID value must match the name of the placeholder exactly.

For example, if you set the Slot Name to My Placeholder, Uniform will generate the value myPlaceholder. If the name of the placeholder is my-placeholder, you must manually change the Public ID value to my-placeholder.

Component: Sample Sublayout

You must define a Canvas component that represents the Sample Sublayout from Sitecore.

  1. Create another component using the following settings:
    • Component Name: Sample Sublayout
    • Slot Name: centercolumn
  2. On the dropdown on the button Save and Close, click Save.
  3. Click Allow in a slot.
  4. Select the component Sample Layout.
  5. Select the slot main.
  6. Click Allow in Sample Layout's main slot.
  7. Click Save and close.

Component: Sample Inner Sublayout

You must define a Canvas component that represents the Sample Inner Sublayout from Sitecore.

  1. Create another component using the following settings:
    • Component Name: Sample Inner Sublayout
    • Slot Name: content
  2. On the dropdown on the button Save and Close, click Save.
  3. Click Allow in a slot.
  4. Select the component Sample Sublayout.
  5. Select the slot centercolumn.
  6. Click Allow in Sample Sublayout's centercolumn slot.
  7. Click Save and close.

Component: Sample Rendering

You must define a Canvas component that represents the Sample Rendering from Sitecore.

  1. Create another component using the following settings:
    • Component Name: Sample Rendering
  2. On the dropdown on the button Save and Close, click Save.
  3. Click Allow in a slot.
  4. Select the component Sample Inner Sublayout.
  5. Select the slot content.
  6. Click Allow in Sample Inner Sublayout's content slot.
  7. Click Save and close.

Composition: Home Page

You must define a Canvas composition that represents the presentation details from the Home item in Sitecore.

  1. In the left menu, click Compositions.
  2. Click (+).
  3. Enter the following values:
    • Select a composition type: Sample Layout
    • Name: Home Page
  4. Click Create.
  5. Under Sample Layout, click (+).
  6. Click Sample Sublayout.
  7. Under Sample Sublayout, click (+).
  8. Click Sample Inner Sublayout.
  9. Under Sample Inner Sublayout, click (+).
  10. Click Sample Rendering.
  11. Click Save and publish.
  12. In your browsers URL bar, notice the structure of the URL. The last part of the URL, after /edit/ is a GUID. This is your Uniform composition ID. Normally you do not need to note this value, but for this exercise you will need it in a later step.

Create the front-end

In the previous section you used Canvas to describe how to arrange the components that make up a web page. The next step is to implement that actual components that will be used to deliver the digital experience to a visitor. This will be done using the front-end framework Next.js.

In this example you only have a single page, so you don't need to worry about routing.

Create web app

Since you are migrating your site to a new front-end, you must create the web app where you will define that front-end.

  1. Open a command-line interface (CLI).
  2. Enter the following commands:
    npx create-next-app mysite
    cd mysite
  3. Add a file .env and define the variables in the table below.
NameValue
UNIFORM_API_TOKENYour Uniform API token
UNIFORM_PROJECT_IDYour Uniform Project ID
UNIFORM_API_URLYour Sitecore URL (must use https://)
UNIFORM_API_SITENAMEMySite
UNIFORM_API_KEYYour Uniform API key
SITECORE_API_KEYYour Sitecore API key or any GUID if you use Sitecore 8.2
  1. If your Sitecore instance uses self-signed SSL certificate, define the extra variable:
    • Name: NODE_TLS_REJECT_UNAUTHORIZED
    • Value: 0
info

The .env file uses simple file format:

# comment
VARIABLE1_NAME=VARIABLE1_VALUE
VARIABLE2_NAME=VARIABLE2_VALUE

Add npm packages

In order to add Uniform functionality to your web app, you must add a number of npm packages. Some of these packages are publically available and some require an npm access token.

  1. Set the following environment variable:
    • Name: NPM_TOKEN
    • Value: Your Uniform npm access token
  2. Add a file .npmrc:
    //registry.npmjs.org/:_authToken=${NPM_TOKEN}
  3. Enter the following commands:
    npm install dotenv @uniformdev/canvas @uniformdev/canvas-react @uniformdev/canvas-sitecore @uniformdev/cli
    npm install @uniformdev/next-server @uniformdev/common-server @uniformdev/common-client @uniformdev/canvas-sitecore

Add Uniform config

You must configure Next.js to load Uniform settings when it runs.

  1. Open the file next.config.js.
  2. Change the contents to the following:
    const { uniformNextConfig } = require('@uniformdev/next-server');
    module.exports = uniformNextConfig();

Create components

You need to create the React components that are used to implement the front-end. This involves porting code from Sitecore to React. The following files on your Sitecore server represent the presentation logic that you will port to React:

ComponentFile
Sample LayoutC:\inetpub\wwwroot\layouts\sample layout.aspx
Sample SublayoutC:\inetpub\wwwroot\layouts\sample sublayout.ascx
Sample Inner SublayoutC:\inetpub\wwwroot\layouts\sample inner sublayout.ascx
Sample RenderingC:\inetpub\wwwroot\xsl\sample rendering.xslt

Component: Sample Layout

In this component, the webcontrol sc:placeholder is replaced with a React component Slot.

Create a file components/SampleLayout.jsx:

import Head from 'next/head';
import { Slot } from '@uniformdev/canvas-react';

export function SampleLayout() {
return (
<>
<Head>
<title>Welcome to Sitecore</title>
</Head>
<div id="MainPanel">
<Slot name="main"></Slot>
</div>
</>
);
}
tip

The Sitecore layout also includes a link to the CSS file /default.css, which is located on the Sitecore server at C:\inetpub\wwwroot\default.css. In order for these styles to be applied to your page, the contents of this css file can be added to the React file styles/global.css.

This file includes a style that sets an image. You must change the URL to be fully qualified by adding the hostname for your Sitecore server. For example, https://yoursitecore/-/media/Default Website/cover.ashx.

Component: Sample Sublayout

Create a file components/SampleSublayout.jsx:

import { Slot } from '@uniformdev/canvas-react';

export function SampleSublayout() {
return (
<div id="CenterColumn">
<Slot name="centercolumn"></Slot>
</div>
);
}

Component: Sample Inner Sublayout

Create a file components/SampleInnerSublayout.jsx:

import { Slot } from '@uniformdev/canvas-react';

export function SampleInnerSublayout() {
return (
<div id="InnerCenter">
<div id="Header">
<img src="https://yoursitecore/-/media/Default Website/sc_logo.ashx" alt="Sitecore" id="scLogo" />
</div>
<div id="Content">
<div id="LeftContent">
<Slot name="content"></Slot>
</div>
</div>
<div id="Footer">
<hr className="divider" />© {new Date().getFullYear()} Sitecore
</div>
</div>
);
}
info

Replace https://yoursitecore with your actual Sitecore URL. Next.js will use this URL during the build process.

Component: Sample Rendering

This component displays fields from the Sitecore data source item. If the data source item is not selected, it uses a context item (a page item) instead. Uniform makes the item available as a prop that is passed to the component. In the next section you will wire this up.

Create a file components/SampleRendering.jsx:

export function SampleRendering({ model }) {
return (
<div>
<h1 className="contentTitle">{model.Title}</h1>

{/* rich text field needs to be rendered via dangerouslySetInnerHTML */}
<div className="contentDescription" dangerouslySetInnerHTML={{ __html: model.Text }}></div>
</div>
);
}
info

The model field name was chosen by a convention that will be explained in next chapters.

Map component name to implementation

Each component defined in Canvas has a public ID. When your web app reads composition definitions from Canvas, the components that are assigned to the composition are identified using this value.

You must provide instructions to your web app on how to map the public ID to the front-end implementation of that component. In your web app, React components provide that implementation.

Create a file lib/resolveRenderer.jsx:

import { SampleLayout } from '../components/SampleLayout';
import { SampleSublayout } from '../components/SampleSublayout';
import { SampleInnerSublayout } from '../components/SampleInnerSublayout';
import { SampleRendering } from '../components/SampleRendering';

export const resolveRenderer = (component) => {
// notice this is Public ID, not Component Name - and it is case-sensitive
if (component.type === 'sampleLayout') {
return SampleLayout;
}

if (component.type === 'sampleSublayout') {
return SampleSublayout;
}

if (component.type === 'sampleInnerSublayout') {
return SampleInnerSublayout;
}

if (component.type === 'sampleRendering') {
return SampleRendering;
}

throw new Error(`Component is not registered: ${component.type}`);
};

Configure page

As its name suggests, the Home Page composition represents the home page for the web app. The Next.js page component must use the React component that represents the composition component.

Replace the contents of the file pages/index.jsx with the following:

import { Composition } from '@uniformdev/canvas-react';
import { resolveRenderer } from '../lib/resolveRenderer';

export default function Home({ composition }) {
return (
<Composition data={composition} resolveRenderer={resolveRenderer}>
{() => resolveRenderer(composition)}
</Composition>
);
}

export { getStaticProps } from '../lib/getStaticProps';
info

This code exports the function getStaticProps from a file that does not exist. This file - and function - will be defined in a later step.

Define the enhancer

Enhancers are an essential part of how Canvas aggregated data from multiple content sources. An enhancer is used to make content from the Sitecore integration that you configured in your Uniform project available to your web app.

You must inject Sitecore item fields into the composition so that the component Sample Rendering can display them on the page.

Create a file lib/enhanceComposition.jsx:

import { EnhancerBuilder, enhance } from "@uniformdev/canvas";
import { createItemEnhancer } from '@uniformdev/canvas-sitecore';

export async function enhanceComposition({ composition, config, pageId, pageData, context, isPreview }) {
const itemEnhancer = createItemEnhancer({
pageId,
pageItem: pageData,
config,
isPreview,
});

const enhancers = new EnhancerBuilder()
.component('sampleRendering', b => b.data('model', itemEnhancer))

await enhance({ composition, enhancers, context });
}
info

This enhancer adds props.model property that is used in components/SampleRendering.jsx file and it will hold all Sitecore fields of the datasource item, or a page item if a datasource item is not selected. The model term was used instead of item because of a uniform nature of the frontend components: they can be reused by different systems that don't have Sitecore's data item concept.

Define getStaticProps

Next.js uses the function getStaticProps during the build process to save data needed to build the page at runtime. This function implements the following logic:

  1. Reads Uniform configuration injected via next.config.js.
  2. Uses CanvasClient to get composition by its ID.
  3. Uses getPageInfo to retrieve page data from Sitecore using SSC and Uniform APIs.
  4. Uses enhanceComposition to enhance the composition.

Create a file lib/getStaticProps.jsx:

// private @uniformdev npm packages
import { throwException } from '@uniformdev/common';
import { parseUniformServerConfig } from '@uniformdev/common-server';
import { noopLogger } from '@uniformdev/common-client';
import { getPageInfo } from '@uniformdev/canvas-sitecore';

// public @uniformdev npm package
import { CanvasClient, CANVAS_PUBLISHED_STATE } from '@uniformdev/canvas';

// read configuration and prepare
const config = parseUniformServerConfig(process.env, noopLogger, true);

import { enhanceComposition } from './enhanceComposition';

export async function getStaticProps(context) {
const slug = '/';

// create the canvas client
const client = new CanvasClient({
apiKey: config.env.UNIFORM_API_KEY ?? throwException('The UNIFORM_API_KEY environment variable is missing'),
projectId: config.env.UNIFORM_PROJECT_ID ?? throwException('The UNIFORM_PROJECT_ID environment variable is missing'),
apiHost: 'https://uniform.app',
});

const { composition } = await client.getCompositionById({
//
// for simplicity of this tutorial, hard-code the composition id
//
compositionId: 'YOUR_UNIFORM_COMPOSITION_ID'',
state: CANVAS_PUBLISHED_STATE
});

const isPreview = false;

let { pageId, pageData, } = await getPageInfo({ slug, config, isPreview });

await enhanceComposition({ composition, pageId, pageData, isPreview });

// set `composition` as a prop to the route
return {
props: {
composition,
},
};
}
info

Replace YOUR_UNIFORM_COMPOSITION_ID' with your Uniform composition ID. The extra single-quote character was added to cause build-time error to make sure you don't miss it. The hard-coded value will be removed in next chapters of this tutorial.

Start the web app

When you run the web app, you should see the page from the default Sitecore site, but Sitecore isn't handling page rendering. Sitecore is only acting as a headless CMS.

  1. On the CLI, enter the following command:
    npm run dev
  2. Open your browser to http://localhost:3000.

Model Builders

Canvas Sitecore integration allows to define a model builder for component. It can be helpful when item fields is not enough and we need to prepare data from backend side.

How to use model builders

Implement Uniform.ModelBuilders.IComponentModelBuilder, Uniform.Platform.Canvas.ModelBuilder interface

public interface IComponentModelBuilder
{
[CanBeNull]
object BuildModel(
[NotNull] Item pageItem,
[NotNull] Item datasourceItem,
[NotNull] IReadOnlyDictionary<string, string> parameters
);
}

pageItem - current page item datasourceItem - current datasource item (can be the same as a page item) parameters - key-value parameters defined for component on Canvas composition <result> - json-serializable object

Register model builder via Sitecore config

<configuration xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore>
<uniform>
<siteConfigurations>
<siteConfiguration name="MySite">
<canvas>
<canvasModelBuilderService ref="uniform/services/canvasModelBuilderService">
<modelBuilders hint="raw:RegisterModelBuilder">
<builder componentId="<CANVAS_COMPONENT_ID>" type="Namespace.ModelBuilderType, Assembly" />
</modelBuilders>
</canvasModelBuilderService>
</canvas>
</siteConfiguration>
</siteConfigurations>
</uniform>
</sitecore>
</configuration>

Update enhancers to use model instead of Sitecore item for particular component.

@uniformdev/canvas-sitecore package contains a few helpers to work with model builders.

  • getModel function

    const model = await getModel({
    id: itemId,
    pageId,
    component,
    config,
    isPreview,
    });
  • create an enhancer from createItemEnhancer function with useModelBuilder option

    const modelEnhancer = createItemEnhancer({
    pageId,
    pageItem: pageData,
    config,
    isPreview,
    useModelBuilder: true,
    });

Model builder example: Sample rendering

Implement Sample Rendering model and model builder

using System.Collections.Generic;

using Sitecore.Data.Items;

using Uniform.ModelBuilders;

namespace MySite.ModelBuilders
{
public class SampleRenderingModel
{
public string Title { get; set; }

public string Text { get; set; }
}

public class SampleRenderingModelBuilder : IComponentModelBuilder
{
public object BuildModel(Item pageItem, Item datasourceItem, IReadOnlyDictionary<string, string> parameters)
{
return new SampleRenderingModel()
{
Title = datasourceItem["Title"],
// Rich Text fields needs to be rendered
Text = ModelBuilderHelper.RenderField(datasourceItem, "Text")
};
}
}
}

Register Sample Rendering model builder

Create App_Config\Include\zzz_MySite\MySite.Uniform.Canvas.config config with the following content

<configuration xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore>
<uniform>
<siteConfigurations>
<siteConfiguration name="MySite">
<canvas>
<canvasModelBuilderService ref="uniform/services/canvasModelBuilderService">
<modelBuilders hint="raw:RegisterModelBuilder">
<sampleRendering componentId="sampleRendering" type="MySite.ModelBuilders.SampleRenderingModelBuilder, MySite" />
</modelBuilders>
</canvasModelBuilderService>
</canvas>
</siteConfiguration>
</siteConfigurations>
</uniform>
</sitecore>
</configuration>

Update enhanceComposition function

import { EnhancerBuilder, enhance } from "@uniformdev/canvas";
import { createItemEnhancer } from '@uniformdev/canvas-sitecore';

export async function enhanceComposition({ composition, pageId, pageData, config, context, isPreview }) {
const modelEnhancer = createItemEnhancer({
pageId,
pageItem: pageData,
config,
isPreview,
useModelBuilder: true
});

const enhancers = new EnhancerBuilder()
.component('sampleRendering', b => b.data('item', modelEnhancer))

await enhance({ composition, enhancers, context });
}