Page personalization and component A/B/n testing
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.
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.
The add-on works in combination with the following features:
-
Personalized page variants created in Pages.
-
A/B/n testing for comparing the performance of two component variants across different segments of your customer base.
-
Analytics data from page and form events.
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.
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.
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.
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.
ImportantStatic 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 variantID
s. The resulting path will have the following structure:
/_variantId_<variantId-1>[/_variantId_<variantId-2>/_variantId_<variantId-3>/.../]/<path>
For example:
-
A page with the path
/foo/bar
and the personalized variant1234
is represented by the path/_variantId_1234/foo/bar
. -
A page with the path
/foo/bar
and component-level variantscomponent1_1234
andcomponent2_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:
-
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:
RequestResponsequery($siteName: String!, $language: String!, $itemPath: String!) { layout(site: $siteName, routePath: $itemPath, language: $language) { item { id version personalization { variantIds } } } }
-
Calls the personalization endpoint with request or user context to determine the page variant or component variants to display.
RequestResponsedata = 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' ] } } } }
-
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:
{
variantId: '_default',
componentVariantIds: [],
}
If the page is personalized, variantId
is specific to the assigned page variant. For example:
{
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:
{
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 |
---|---|---|
|
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
After adding the RequestResponse
If a page contains A/B/n testing, its tested component variants will be identified as: RequestResponse
|
|
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 |
|
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 |