[Personalize] Support dynamic token replacement from decision tables#2190
Open
bransbury wants to merge 1 commit into
Open
[Personalize] Support dynamic token replacement from decision tables#2190bransbury wants to merge 1 commit into
bransbury wants to merge 1 commit into
Conversation
bransbury
commented
Mar 30, 2026
Author
There was a problem hiding this comment.
Looks like this was committed erroneously in the past so I've removed and added to .gitignore. This is unrelated to the main changes
0e814c6 to
ff531be
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description / Motivation
This PR adds support for dynamic token replacement from Sitecore Personalize decision table responses across the JSS personalization pipeline.
Problem
When Sitecore Personalize decision tables return tokens (e.g.
{ firstName: "Bob", city: "Portland" }), there is currently no mechanism in JSS to apply these values to layout data. Content authors can configure{{firstName}}placeholders in their content, but the values are never substituted at render time.Solution
New
token-replaceutility (sitecore-jss/src/personalize/token-replace.ts):replaceTokens(): substitutes{{key}}and{{key|fallback}}mustache-style tokens in stringsreplaceTokensInObject(): recursively walks layout data and applies token replacement to all string values{{name|Valued Customer}}), whitespace-trimmed keys,removeUnmatchedoption, andonUnmatchedcallback__proto__,constructor,prototypekeys are skipped)Next.js middleware (
personalize-middleware.ts):x-sc-personalize-tokensresponse headerNext.js page-props plugin (
personalize.tstemplate):x-sc-personalize-tokensheader from the incoming requestreplaceTokensInObject()to layout data afterpersonalizeLayout()runsProxy PersonalizeHelper (
sitecore-jss-proxy):getVariantIds()now returns{ variantIds, tokens }to pass tokens throughpersonalizeLayoutData()after layout personalization🛠 Breaking Changes
PersonalizeHelper.getVariantIds()insitecore-jss-proxychanged its return type fromPromise<string[]>toPromise<{ variantIds: string[]; tokens: Record<string, string> }>. This is aprotectedmethod — only subclasses that override it need to update their signature. This is unlikely to affect most consumers since the proxy package is used by non-Next.js rendering hosts and this method is not part of the public API surface.Testing Details
New test coverage:
token-replace.test.ts: 25+ test cases covering: single/multiple token replacement, fallback values, whitespace trimming,removeUnmatched,onUnmatchedcallback, nested object traversal, array handling, null/undefined safety, prototype pollution guard, ReDoS guard, HTML/URL content, special regex characters in valuespersonalize-middleware.test.ts: updated tests for token forwarding via header, multi-execution token aggregation, base64 encodingPersonalizeHelper.test.ts: updated tests for token application to layout data, empty tokens handling, collision detectionTypes of changes
Packages affected
sitecore-jsstoken-replace.tsutility, exported frompersonalizesubpathsitecore-jss-nextjsPERSONALIZE_TOKENS_HEADERsitecore-jss-proxyPersonalizeHelperapplies tokens to layout data (getVariantIdsreturn type)create-sitecore-jsspersonalize.tsplugin to consume tokens