Skip to main content

JSS (Optimize & Deploy)

This section describes how to add tracking and edge-based 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 the boilerplate component that represents a page using Uniform and JSS:

note

This is the "before" code.

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}>                <Placeholder name="jss-site-content" rendering={route} />            </SitecoreContext>        </StaticAssetContextProvider>    );};

The following adds the tracker:

import { useSitecoreTracker } from '@uniformdev/tracking-react';
const SitecoreRoute = ({ layoutData, assetPrefix = '' }) => {    const route = layoutData?.sitecore?.route;    //    //START: Uniform tracker code    const sitecoreContext = layoutData?.sitecore?.context;    useSitecoreTracker(sitecoreContext, {      type: "jss",    });    //    //END: Uniform tracker code    //    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}>          <Placeholder name="jss-site-content" rendering={route} />        </SitecoreContext>      </StaticAssetContextProvider>    );};

Add personalization context provider#

  1. Add the following import statement:

    import { SitecorePersonalizationContextProvider } from '@uniformdev/personalize-react';
  2. Wrap the StaticAssetContextProvider component in the following tag:

    <SitecorePersonalizationContextProvider  contextData={sitecoreContext}  personalizationMode="jss-esi"  sitecoreApiKey=""  sitecoreSiteName="">  ...</SitecorePersonalizationContextProvider>
  3. For the prop sitecoreApiKey, add the JSS API key for your Sitecore instance.

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

  5. The return statement for the component should look something like the following:

    return (  <SitecorePersonalizationContextProvider    contextData={sitecoreContext}    personalizationMode="jss-esi"    sitecoreApiKey="11112222-3333-4444-5555-666677778888"    sitecoreSiteName="my-jss-site"  >    <StaticAssetContextProvider assetPrefix={assetPrefix}>      <Head>        <title>{route?.fields?.pageTitle?.value || 'Page'}</title>        <link rel="shortcut icon" href="/favicon.ico" />      </Head>
          <SitecoreContext componentFactory={componentFactory} layoutData={layoutData}>        <Placeholder name="jss-site-content" rendering={route} />      </SitecoreContext>    </StaticAssetContextProvider>  </SitecorePersonalizationContextProvider>)

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

  1. Add the following import statement:

    import { EsiPlaceholder } from '@uniformdev/esi-jss-react';
  2. Add the placeholder component

    <EsiPlaceholder rendering={route} />
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-based 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-based 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-based personalization#

When the Nextjs application is exported, the application requests content from Sitecore layout service. Uniform extends layout service to include instructions for edge-based 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