Page personalization and component A/B/n testing

Version: 22.x

The XM Cloud add-on integrates Next.js applications with the page personalization, component A/B/n testing, and analytics features of XM Cloud. The add-on uses Next.js Middleware architecture to enable personalization and A/B/n testing, combined with the Events package in the Sitecore Cloud SDK to capture page view events in the user's browser.

Note

Component A/B/n testing requires JSS version 22.1 or later.

The add-on is automatically included in all projects created using the starter kit, so you don't need to manually configure anything to enable personalization or A/B/n testing. For other projects, you can enable the add-on using the JSS initializer.

The add-on includes the following elements for supporting personalization and A/B/n testing:

  • A Next.js middleware plugin that calls the Cloud SDK.

  • A React component for page view events using the Cloud SDK.

  • A page props factory plugin.

  • Additional environment variables for configuration.

Note

The add-on works in combination with the following features:

When published, page and component variants are stored in the page layout data in Experience Edge.

Page personalization overview

The following diagram shows how JSS sends a request to determine which variant of a personalized page to render for a visitor, based on how personalization is set up for that page. In this diagram, the middleware used to communicate with Sitecore Personalize is Cloud SDK.

Sequence diagram showing the process for fetching personalized page variants.

Personalize identifies the page variant to display based on the context of the site visit, such as the visitor's geolocation details and their local time. It returns a page variant by rewriting the page path (personalized rewrite path).

The Next.js app parses the personalized rewrite path to get the details of the page variant. It then renders the layout and displays the correct personalized page to the visitor. Each time someone visits the page, the Cloud SDK captures a page view event that can be used in web analytics, segmentation, personalization, and more.

Note

Your site must have analytics identifiers for analytics to work. They're added automatically in most cases, such as when you create an environment using the starter kit.

Component A/B/n testing overview

The following diagram shows how JSS requests and renders component variants whenever someone visits a page on which one or more component A/B/n tests are running. In this diagram, the middleware used to communicate with Personalize is Cloud SDK.

Sequence diagram showing the process for fetching component variants.

When the visitor accesses the page, a request is sent to Personalize. If component A/B/n tests are running on the page, Personalize selects one variant of the component being tested and returns the corresponding variant ID (if more than one component is being tested, it returns a variant ID for each of those components). The component ID or IDs are then used to fetch layout data and are added to the personalized rewrite path for the page.

Understanding the personalized rewrite path

The personalization implementation in the Next.js XM Cloud add-on uses a rewrite path to identify variants for personalization and A/B/n testing.

The rewrite path is:

  • Set by Personalize middleware, based on the identified page or component variants.

  • Read by the Next.js app to manipulate the layout and feed to page view events.

  • Used to enable static generation for personalized page variants.

    Important

    Static generation does not currently work with component-level A/B/n testing.

The implementation encapsulates the logic for these processes so that you don't have to manipulate this path directly. However, it's helpful to understand how these paths are constructed to help you troubleshoot or customize them.

For page personalization, the path includes a single page-level variantID. For component A/B/n testing, the path includes one or more component-level variantIDs. The resulting path will have the following structure:

RequestResponse
/_variantId_<variantId-1>[/_variantId_<variantId-2>/_variantId_<variantId-3>/.../]/<path>

For example:

  • A page with the path /foo/bar and the personalized variant 1234 is represented by the path /_variantId_1234/foo/bar.

  • A page with the path /foo/bar and component-level variants component1_1234 and component2_5678 is represented by the path /_variantId_component1_1234/_variantId_component2_5678/foo/bar.

APIs

The XM Cloud add-on uses the following code artifacts to render personalized page variants:

PersonalizeMiddleware

PersonalizeMiddleware is a Next.js middleware handler that enables page personalization and A/B/n testing.

The middleware:

  1. Makes a call to Experience Edge to get personalization information about the page, including variants.

    The following example query requests a page variant ID for personalization:

    RequestResponse
    query($siteName: String!, $language: String!, $itemPath: String!) {
      layout(site: $siteName, routePath: $itemPath, language: $language) {
        item {
          id
          version
          personalization {
            variantIds
          }
        }
      }
    }
  2. Calls the personalization endpoint with request or user context to determine the page variant or component variants to display.

    RequestResponse
    data = await this.graphQLClient.request<PersonalizeQueryResult>(this.query, {
      siteName,
      itemPath,
      language,
    });

    The following example response includes a page variant ID as requested:

    RequestResponse
    {
      layout: {
        item: {
          id: '35D149DAEB2047E185F14E2BC484AF58',
          version: 1,
          personalization: { variantIds: [ '9521beac72a44ab4a457082f636910c6' ] }
        }
      }
    }
    
  3. Rewrites the response to the specific page variant or component variants using the personalized rewrite path.

 

normalizePersonalizedRewrite

The normalizePersonalizedRewrite function removes personalization data from a personalized rewrite path so that layout data can be appropriately retrieved. The function is used by the Page Props Factory extractPath function defined in the src\lib\page-props-factory\extract-path.ts file of a Next.js application with the Personalize add-on installed.

 

getPersonalizedRewriteData

The getPersonalizedRewriteData function extracts personalization data (variantId and componentVariantIds) from a personalized rewrite path. The Page Props Factory plugin for personalization, defined in the src/lib/papge-props-factory/plugins/personalize.ts file, passes the data to the personalizeLayout function.

 

personalizeLayout

The personalizeLayout function modifies layout data to use a specific variant based on the provided variantId parameter and an optional componentVariantIds parameter. The default layout is then modified based on the matching variants. The function also sets the variantId property on the Sitecore context.

 

CdpHelper

The CdpHelper class provides the getPageVariantId function that gets the page variant identifier in the format required for the pageVariantId parameter of a page view event.

 

getGroomedVariantIds

The getGroomedVariantIds function accepts a flat list of variantIds and returns an object containing one page-level variantId and the componentVariantIds array.

If the page is not personalized and does not have A/B/n testing running on any components, the object contains default data:

RequestResponse
{
  variantId: '_default',
  componentVariantIds: [],
}

If the page is personalized, variantId is specific to the assigned page variant. For example:

RequestResponse
{
  variantId: 'page-variant-12345',
  componentVariantIds: [],
}

If the page includes any component A/B/n testing, the componentVariantIds array lists the IDs of the assigned variant for each component. The following example represents a page containing two components with A/B/n testing:

RequestResponse
{
  variantId: '_default',
  componentVariantIds: ['component-ABC_variant-123', 'component-XYZ_variant-456'],
}

Environment variables

You use environment variables to configure personalization in a JSS Next.js app.

The following table lists the environment variables specific to personalization.

Variable

Description

Values

NEXT_PUBLIC_PERSONALIZE_SCOPE 

Optional.

Unique page identifiers are used to run personalization flows and analytics. However, if any of your pages were created through site serialization, identical page identifiers might exist across different XM Cloud environments.

Use this variable to isolate personalization data between such XM Cloud environments. It creates a unique page or component personalization identifier for each environment.

Default: n/a

If you don't use the variable, the default structure for identifying a personalized page is:

RequestResponse
embedded_<pageId>_<language>

After adding the PAGES_PERSONALIZE_SCOPE variable with a value of myEnv, for example, that ID is changed to:

RequestResponse
embedded_myEnv_<pageId>_<language>

If a page contains A/B/n testing, its tested component variants will be identified as:

RequestResponse
component_myEnv_<pageId>_<componentId>_<language>

PERSONALIZE_MIDDLEWARE_CDP_TIMEOUT 

Optional.

Value in milliseconds. It allows you to fine-tune the timeout for CDP calls within the personalization middleware. If the timeout is exceeded, the user sees the default page.

Default: 400

PERSONALIZE_MIDDLEWARE_EDGE_TIMEOUT 

Optional.

Value in milliseconds. It allows you to fine-tune the timeout for Experience Edge calls within the personalization middleware. If the timeout is exceeded, the user sees the default page.

Default: 400

Do you have some feedback for us?

If you have suggestions for improving this article,