Skip to main content

JSS (Optimize & Deploy)

This section describes how to add tracking and edge-side personalization to a site that uses Uniform Optimize and Deploy.

note

These instructions assume you already have a front-end built using JSS and Nextjs.

note

Currently Uniform documentation only covers JSS sites built using Nextjs. If you are using a different front-end framework, contact your Uniform representative for guidance.

note

Optimize for Sitecore does not currently support personalization on Nextjs sites that use client-side routing (i.e. SPA navigation).

tip

A starter application is available that provides a complete example of a site with tracking and personalization configured If you prefer to start your learning from a complete example, this starter application is what you should use. This application is available on GitHub.

Add npm packages#

Add the following npm packages to your Nextjs application:

  • @uniformdev/esi-jss-react
  • @uniformdev/tracking-react

Add tracker to page#

The Uniform tracker must be added to every page you want to track.

  • The Sitecore context must be provided to the tracker.

The following is an example a JSS page:

const SitecoreRoute = ({ layoutData, assetPrefix = '' }) => {  const route = layoutData?.sitecore?.route;
  return (    <StaticAssetContextProvider assetPrefix={assetPrefix}>      <Head>        <title>{route?.fields?.pageTitle?.value || 'Page'}</title>        <link rel="shortcut icon" href="/favicon.ico" />      </Head>
      <SitecoreContext componentFactory={componentFactory} layoutData={layoutData}>        <MainLayout route={route} />      </SitecoreContext>    </StaticAssetContextProvider>  );};

The following is the MainLayout component:

import React from 'react';import {   Placeholder,} from '@sitecore-jss/sitecore-jss-react';
export default function MainLayout({ route }) {  return (    <div>      <main>        <Placeholder name="jss-site-content" rendering={route} />      </main>      <Footer/>    </div>  )}

To add the Uniform tracker to the MainLayout component, add the following:

import React from 'react';import {   Placeholder,  useSitecoreContext,} from '@sitecore-jss/sitecore-jss-react';import { useSitecoreTracker } from '@uniformdev/tracking-react';
export default function MainLayout({ route }) {  const { sitecoreContext } = useSitecoreContext();  useSitecoreTracker(sitecoreContext, {    type: 'jss',  });  return (    <div>      <main>        <Placeholder name="jss-site-content" rendering={route} />      </main>      <Footer/>    </div>  )}

Add personalization context provider#

  1. In MainLayout component, add the following:
import React from 'react';import {   Placeholder,  useSitecoreContext,} from '@sitecore-jss/sitecore-jss-react';import { useSitecoreTracker } from '@uniformdev/tracking-react';import { SitecorePersonalizationContextProvider } from '@uniformdev/personalize-react';
export default function MainLayout({ route }) {  const { sitecoreContext } = useSitecoreContext();  useSitecoreTracker(sitecoreContext, {    type: 'jss',  });  return (    <SitecorePersonalizationContextProvider      contextData={sitecoreContext}      personalizationMode="jss-esi"      sitecoreApiKey=""      sitecoreSiteName=""    >      <div>        <main>          <Placeholder name="jss-site-content" rendering={route} />        </main>        <Footer/>      </div>    </SitecorePersonalizationContextProvider>  )}
  1. For the prop sitecoreApiKey, add the JSS API key for your Sitecore instance.

  2. For the prop sitecoreSiteName, set the name of the Sitecore site.

Add ESI Context placeholder#

Uniform adds a placeholder named esi-context to the page layout. This placeholder is populated with a component that is responsible for generating the context on the edge that powers edge-side personalization.

This placeholder must be added to Nextjs application, and it must be added before any placeholders that hold personalized components. A special component is used to add the placeholder to the page.

When the components inside this placeholder are rendered, there is no output. This means you do not need to worry that adding this placeholder could break your layout.

In MainLayout component, add the following:

import React from 'react';import {   Placeholder,  useSitecoreContext,} from '@sitecore-jss/sitecore-jss-react';import { useSitecoreTracker } from '@uniformdev/tracking-react';import { SitecorePersonalizationContextProvider } from '@uniformdev/personalize-react';import { EsiPlaceholder } from '@uniformdev/esi-jss-react';
export default function MainLayout({ route }) {  const { sitecoreContext } = useSitecoreContext();  const esiEnabled = route.placeholders['esi-context']?.length > 0;  useSitecoreTracker(sitecoreContext, {    type: 'jss',  });  return (    <SitecorePersonalizationContextProvider      contextData={sitecoreContext}      personalizationMode="jss-esi"      sitecoreApiKey=""      sitecoreSiteName=""    >      {esiEnabled && <EsiPlaceholder rendering={route} />}      <div>        <main>          <Placeholder name="jss-site-content" rendering={route} />        </main>        <Footer/>      </div>    </SitecorePersonalizationContextProvider>  )}
note

For more information about the ESI Context, see the reference section.

Update component factory#

JSS uses a component factory to resolve the component name returned from Layout Service to a React component. Uniform's edge-side personalization depends on a number of custom React components. These components must be registered with the component factory.

When using Nextjs and JSS, the component factory is configured in the file src/componentFactory.js.

The following is the boilerplate component factory:

note

This is the "before" code.

import Hero from './renderings/Hero';
const components = new Map();components.set('Hero', Hero);
export default function componentFactory(componentName) {  return components.get(componentName);}

The following registers the React components that Uniform adds to the Layout Service in order to support edge-side personalization:

import Hero from './renderings/Hero';////START: Uniform personalization codeimport {   EsiChoose, EsiInclude, EsiOtherwise,   EsiWhen, EsiNullComponent, EsiForEach,   EsiAssign, EsiText, EsiScript, EsiNoOutput,   EsiContextCsr, EsiContextSsr } from '@uniformdev/esi-jss-react';////END: Uniform personalization code
const components = new Map();components.set('Hero', Hero);////START: Uniform personalization codecomponents.set('EsiChoose', EsiChoose); components.set('EsiInclude', EsiInclude);components.set('EsiOtherwise', EsiOtherwise);components.set('EsiWhen', EsiWhen);components.set('EsiNullComponent', EsiNullComponent);components.set('EsiForEach', EsiForEach);components.set('EsiAssign', EsiAssign);components.set('EsiText', EsiText);components.set('EsiScript', EsiScript);components.set('EsiNoOutput', EsiNoOutput);components.set('EsiContextCsr', EsiContextCsr);components.set('EsiContextSsr', EsiContextSsr);////END: Uniform personalization code
export default function componentFactory(componentName) {  return components.get(componentName);}

Enable edge-side personalization#

When the Nextjs application is exported, the application requests content from Sitecore layout service. Uniform extends layout service to include instructions for edge-side personalization. However, those instructions are only included when a client indicates those instructions are needed. In a Nextjs application, this is accomplished using an environment variable.

Add the following to the .env file for the Nextjs application:

UNIFORM_OPTIONS_ESI=true