Integrate Salesforce Personalization with Frontend Frameworks

Seamlessly integrate Salesforce Personalization into frontend frameworks such as React, Vue, Angular, and others using a component-based approach. With this approach, you can create custom components that register themselves as content zones, ensuring robust, reliable delivery and rendering of personalized content.

Traditional DOM manipulation by the SDK can conflict with the virtual DOM or rendering strategies of modern frameworks, causing personalized content to disappear. By creating a custom component that registers itself as a content zone handler, you make sure that personalized content is delivered and rendered using your framework’s own methods. This approach works well for any component-based frontend architecture.

Key Concepts 

Web Personalization Manager (WPM)

The UI for previewing and managing personalized content zones.

Content Zone Handler

A registration for a specific area or component in your app that can be personalized. Use the Personalization module's Config.ContentZoneHandler.set function to register your handler, providing a unique name and configuration object.

Register a Content Zone Handler 

To enable personalization, register each content zone handler using the set function. This function ensures that your content zone is recognized by the Personalization module and can be targeted for dynamic content replacement.

1SalesforceInteractions.Personalization.Config.ContentZoneHandler.set(
2  (ContentZoneHandlerName: String), // For example, "home_banner"
3  (ContentZoneHandlerProperties: Object),
4);

This table describes the parameters required by the set function:

ParameterTypeRequiredDescription
ContentZoneHandlerNameStringYesUnique, machine-friendly name for the content zone handler (for example, home_banner).
ContentZoneHandlerPropertiesObjectYesConfiguration object defining how the content zone behaves and is rendered.

ContentZoneHandlerProperties Interface 

The ContentZoneHandlerProperties interface defines the configuration object used when registering a content zone handler.

1interface ContentZoneHandlerProperties {
2  onReady: (content: string, metadata: ContentZoneHandlerMetadata) => void;
3  onRevert?: (metadata: ContentZoneHandlerMetadata) => void;
4  onHighlight?: (highlight: boolean, metadata?: ContentZoneHandlerMetadata) => void;
5  path?: string;
6  label?: string;
7}
PropertyRequired?Description
onReadyYesonReady is called when personalized content is ready for rendering. This property receives personalized content from Personalization as an input parameter and enables you to define custom rendering logic inside your component.
onRevertNo, but recommendedUsed only at design time (not at runtime). onRevert is called when a preview is cancelled in WPM. When a business user cancels a preview in WPM, your page must revert to rendering the original, non-personalized content of the page.
labelNoUser-friendly name of the registered content zone handler that appears within WPM. If not provided, this property defaults to showing the handler name.
pathNoUsed only at design time (not at runtime). Specifies a CSS selector that WPM uses to visually highlight the content zone handler in the page editor. This helps business users easily locate and identify the content zone handler’s position on the page when setting up personalization experiences.
onHighlightNoUsed only at design time (not at runtime). Custom logic for WPM to visually highlight the content zone handler. Use onHighlight only if you can’t use the path property. For example, when your component uses Shadow DOM or other advanced rendering techniques that make CSS selectors unreliable.

Don’t define both path and onHighlight at the same time.

Important

Example: Personalization Content Handler using Vanilla JavaScript 

Here’s an example that demonstrates how to implement a content zone handler using vanilla JavaScript:

1<div id="hero_banner_element"></div>
2
3<script type="text/javascript">
4  window.SalesforceInteractions.Personalization.Config.ContentZoneHandler.set(
5    /** Define the content zone name */
6    "hero_banner",
7
8    /** Define the content zone configuration */
9    {
10      /** Optionally define a content zone label that will be displayed in the UI */
11      label: "Hero Banner",
12
13      /** Optionally specify a CSS selector for the content zone. 
14                It will be used to highlight the content zone on the page in WPM */
15      path: "#hero_banner_element",
16
17      /** Set onReady function to render personalized content on the page.
18                Define any custom logic here */
19      onReady: (content) => {
20        document.querySelector("#hero_banner_element").innerHTML = content;
21      },
22
23      /** Optionally revert content to its original state. */
24      onRevert: () => {
25        document.querySelector("#hero_banner_element").innerHTML = "";
26      },
27    },
28  );
29</script>

Example: Personalization Content Handler React Component 

Here’s an example that demonstrates how to implement a custom content handler component in React. This component registers itself as a content zone handler and manages the rendering of personalized content:

1import React, { useEffect, useState } from "react";
2
3export const PersonalizationContentHandler = ({ children, contentZoneName, contentZoneLabel }) => {
4  /** Define state variable for Personalized Content */
5  const [personalizedContent, setPersonalizedContent] = useState(undefined);
6  /** Define state variable for your component's elementId the unique CSS selector */
7  const [elementId, setElementId] = useState(undefined);
8  /** Initialize the component */
9  useEffect(() => {
10    /** Generate elementId for the unique CSS selector */
11    setElementId(`__sf_personalization_contentzonehandler_${contentZoneName}`);
12    /** Register Content Zone Handler */
13    window.SalesforceInteractions.Personalization.Config.ContentZoneHandler.set(
14      /** Use content zone name from an attribute of the component */
15      contentZoneName,
16      {
17        /** Use content zone label from an attribute of the component */
18        label: contentZoneLabel,
19        /** Generate a unique CSS selector for the component based on the generated elementId */
20        path: `#${elementId}`,
21        /** Set onReady function. 'handleReady' function is defined below */
22        onReady: handleReady,
23        /** Set onRevert function. */
24        onRevert: () => {
25          /** Reset the value of the 'personalizedContent' state variable  */
26          setPersonalizedContent(undefined);
27        },
28      },
29    );
30    return () => {
31      /** Deregister content zone handler at cleanup */
32      window.SalesforceInteractions.Personalization.Config.ContentZoneHandler.set(contentZoneName, {
33        onReady: () => {},
34      });
35    };
36  });
37  const handleReady = (content) => {
38    /** Assign personalized content returned by Personalization to the 'personalizedContent' state variable */
39    setPersonalizedContent(content);
40  };
41  /** Render personalized content, if available  */
42  /** Content is wrapped with a DIV that has a unique ID attribute */
43  if (personalizedContent) {
44    return <div id={elementId} dangerouslySetInnerHTML={{ __html: personalizedContent }} />;
45  } else {
46    /** Render original content if personalized content is not available  */
47    /** Content is wrapped with a DIV that has a unique ID attribute */
48    return <div id={elementId}>{children}</div>;
49  }
50};

Here’s how you can use the custom content handler component in your application.

1<PersonalizationContentHandler contentZoneName="ProductRecs" contentZoneLabel="Product Recs">
2  <h1>Non-personalized content</h1>
3  <p>This content will be replaced with Personalized Content</p>
4</PersonalizationContentHandler>

Best Practices 

  • Each content zone handler must have a unique, machine-friendly name.
  • Implement onRevert for proper WPM preview/cancel support.
  • Use path for simple highlight scenarios; use onHighlight for advanced or Shadow DOM cases.
  • The onReady callback must render the personalized content. If not set, show the original children.
  • Unregister or reset handlers on component unmount if needed.
  • The label property makes the handler user-friendly in WPM.

Troubleshooting 

  • If personalized content disappears, ensure you are not manipulating the DOM outside React.
  • If preview cancel in WPM does not work, implement onRevert.
  • If WPM cannot highlight your zone, check your path or implement onHighlight.

See Also