Sitemap Implementation
The Marketing Cloud Personalization Sitemap system is a configuration-driven integration layer that executes within and is deployed by the Personalization module of the Salesforce Interactions SDK. A Sitemap is developed using the SDK to integrate with a specific site and map key business objects into the Personalization system through event capture. A Sitemap includes page type information, which can additionally include catalog items such as products, articles, content, and categories that support the ability to gauge user interest against the catalog.
For more information on the Personalization Sitemap, see Sitemap Overview. For more information on the Personalization data model, see Data Model.
In This Article
This article details the following topics related to the implementation of a Personalization Sitemap.
- Sitemap Configuration Type Definitions
- Sitemap API
- Single Page App Handling
- Sitemap Localization Implementation
Example Sitemaps
The following is a list of example Sitemaps we've created for different types of business websites that depict how you could approach designing a Sitemap for your Personalization implementation. While the JavaScript and HTML code in these example Sitemaps are only for reference purposes, they can give you a head start in developing the Sitemap for your implementation.
A SiteMapConfig
consists of the following three, separate configurations.
global
: Theglobal
configuration contains objects to be monitored by Personalization on all page type configuration objects, and the default page configuration (if defined) of your site.pageTypes
: ThepageTypes
configuration contains objects used to detect/match each different page type to be monitored on your site.pageTypeDefault
: If defined, the objects configured inpageTypeDefault
are matched when allPageConfig
objects in thepageTypes
array resolve tofalse
. Do remember that thepageTypeDefault
matches this way only when the sitemap contains at least one validly constructedPageConfig
object. When using theSalesforceInteractions
namespace, an interaction must be provided forpageTypeDefault
.
The following sections describe how the preceding Sitemap configuration types are processed and provide additional information about each configuration type.
When the configuration for either a PageConfig
object inside the pageTypes
array or the pageTypeDefault
matches a page on the site, the matched configuration merges with anything defined within GlobalConfig
. Individual attributes are merged in the following manner.
locale
: the matchedPageConfig
orDefaultPageConfig
takes precedencecontentZones
: concatenatelisteners
: concatenateonActionEvent
: the function for the matchedPageConfig
orDefaultPageConfig
executes first, followed by the function for theGlobalConfig
The result of this merge is then evaluated as expected.
GlobalConfig
defines the additional data to be tracked if a PageConfig
or DefaultPageConfig
matches a specific page.
Page type configurations use a pageTypes
array to declare how to detect that a given URL or loaded page is one of the known page types. Each page type configuration must contain properties for name
, action
, and isMatch
, which declares the function used to detect that page type. Additionally, individual page type configurations can declare Content Zones representing key parts of a page designed for personalization adjustments. The configurations can also declare other event listeners for a given page type, such as an "add to cart" listener. Page types can map to more than a single page; for example, while the Home page is an example of a page type with only a single instance of a page, the product display page (PDP) type would have separate URLs for every product on the site, but only a single page type.
For more information on page types, refer to the Page Types documentation.
PageConfig
defines the data to be tracked for a specific page. The PageConfig
object accepts the following fields.
The following table describes the fields that a PageConfig
accepts.
Field | Expected Value Type | Required? | Description | Namespace |
---|---|---|---|---|
name | String | Yes | The page type that gets sent in the event when this configuration is evaluated. Example: Homepage, Product Detail | Both |
isMatch | () => boolean | Promise<boolean> | Yes | The function provided here is evaluated when the sitemap is deciding which PageConfig to evaluate. The sitemap only evaluates the first PageConfig whose isMatch resolves to true . If no isMatch resolves to true , then the pageTypeDefault configuration runs. | Both |
locale | String | No | The locale of the page (for example, en_US ). Use locale only if you have catalog localization enabled. | Both |
action | String | No | The name of the action dispatched in the event when this configuration is evaluated. Important: Capture actions only if they’re necessary for personalization and targeting. Actions must have names that can be reused across users and sessions. If you dynamically populate action names, ensure that these names stay consistent across sessions for any user performing the action. Dynamic user information in action names can cause issues and should be avoided whenever possible. For more information and best practices on using actions, see Best Practices For Using Actions. | Evergage |
itemAction | String | No | The name of the itemAction dispatched in the event when this configuration is evaluated. | Evergage |
interaction | Interaction , CatalogObjectInteraction , CartInteraction , or OrderInteraction | No | An object describing the interaction on the page. For more information, refer to the Interaction section of this article. For more information and best practices on using actions, see Best Practices For Using Interactions. | SalesforceInteractions |
catalog | CatalogConfig | No | The catalog data to be captured. For more information, refer to the CatalogConfig section of this article. | Evergage |
cart | CartConfig | No | The cart data to be captured. For more information, refer to the CartConfig section of this article. | Evergage |
order | OrderConfig | No | The order data to be captured. For more information, refer to the OrderConfig section of this article. | Evergage |
contentZones | ContentZone[] | No | The content zones defined in the sitemap determine where Personalization campaigns are rendered throughout a website. Personalization templates reference these content zones for targeting within campaigns. For more information on content zones, refer to the Content Zones documentation. | Both |
listeners | Listener[] | No | The event listeners to be bound when this configuration is evaluated. For more information, refer to the Listeners section of this article. | Both |
onActionEvent | (event: ActionEvent) => ActionEvent | No | The onActionEvent function modifies the outgoing ActionEvent . This function runs whenever the sitemap builds an ActionEvent before sending it to Personalization. The sitemap builds the ActionEvent as a result of calling the sendEvent function or building a PageConfig array. If the GlobalConfig and a matched PageConfig array contain the onActionEvent function, then both functions are executed. The function in PageConfig is executed before executing the function in the GlobalConfig array. | Both |
DefaultPageConfig
defines the default page configuration to use if no other page types are matched. When using DefaultPageConfig
with the SalesforceInteractions
namespace, an interaction must be provided.
CatalogConfig
defines the catalog data to be captured and accepts the following fields. A catalog
object accepts the following fields.
Only available in the SalesforceInteractions
namespace.
The ItemType
in a CatalogConfig
is defined in the Catalog and Profile Objects section of the Personalization UI. An ItemType
can refer to items such as products, content, blogs, or any other catalog object, whether built in or user-defined. The following table describes the fields that an ItemType
array accepts.
Field | Expected Value Type | Required? | Description |
---|---|---|---|
_id | string | () => string | () => Promise<string | () => string> | Yes | The ID of the catalog item. This field is required for an item to be tracked. Important: When capturing catalog items IDs, avoid capturing line break characters (\n ). This character isn't supported in IDs of catalog items, interactions, and actions. Including line breaks in the IDs can cause issues in the UI. |
categories | string[] | () => string[] | () => Promise<string[] | () => string[]> | No | The categories the catalog item belongs to. |
<attributes> | value | () => value | No | Use this field to define standard, built-in item attributes. Examples of attributes include _id , name , price , and so on. |
relatedCatalogObject | string[] | () => string[] | () => Promise<string[] | () => string[]> | No | Catalog objects can be assigned to other catalog objects to describe them in more detail. When so assigned, it is considered a related catalog object. |
attributes | value | () => value | No | Custom attributes on an item, as defined in the Catalog Setup section of the Personalization UI. |
For more details on catalog items and item attributes, see Create a Custom Catalog Object.
CartConfig
defines the cart data to be captured. The cart
object accepts the following fields.
Only available in the SalesforceInteractions
namespace.
When including a CartConfig
in a pageType
, ensure that it follows the following structure.
Only available in the SalesforceInteractions
namespace.
Additionally, a user's cart can be emptied by sending an event with an empty array of LineItems
.
OrderConfig
defines the order data to be captured. An order
object accepts the following fields.
Only available in the Evergage
namespace.
LineItem
represents a single item in a cart/transaction. A LineItem
object accepts the following fields.
Only available in the Evergage
namespace.
Interaction
represents the interaction the user is taking on the page. An Interaction
object accepts the following fields.
Only available in the SalesforceInteractions
namespace.
CatalogObjectInteraction
is an extension of Interaction
that accepts a catalogObject
. A CatalogObjectInteraction
object accepts the following fields.
Only available in the SalesforceInteractions
namespace.
For all CatalogObjectInteractions
, refer to the CatalogObjectInteraction documentation.
CartInteraction
is an extension of Interaction
that accepts information about a cart. A CartInteraction
object accepts the following fields.
Only available in the SalesforceInteractions
namespace.
In a CartInteraction
, LineItem
accepts the following fields.
For all CartInteractions
, refer to the CartInteraction documentation.
OrderInteraction
is an extension of Interaction
that accepts information about an order. An OrderInteraction
object accepts the following fields.
Only available in the SalesforceInteractions
namespace.
In an OrderInteraction
, LineItem
accepts the following fields.
For all OrderInteractions
, refer to the OrderInteraction documentation.
The Personalization module of the Salesforce Interactions SDK includes the following utility function that is especially helpful for building LineItems.
The preceding utility function returns a LineItem
constructed from the data already captured on the page using the given quantitySelector
to determine the number of items in the line item.
The DefaultPageConfig
defines what data is tracked only if all other PageConfig
s resolve to false
.
The DefaultPageConfig
accepts the following fields.
The DefaultPageConfig
works only when the sitemap contains at least one validly constructed PageConfig
object.
The Sitemap API is scoped on the window
under Evergage
.
Initialize the sitemap process using the provided configuration. Events are not sent to Personalization unless this function is called.
A small library for modern browsers that provides jQuery-style syntax to wrap modern Vanilla JS features and select elements from the DOM. For more information on Cash
, refer to the Cash documentation.
Send a custom event to Personalization.
Get the current page state, including values in the configuration that have already been resolved.
Create a listener.
You can use a listener to "listen" for user actions on a page, capture information from that action, and initiate a function or action based on the captured information. Listeners are structurally similar to jQuery's event listeners.
The following are examples of simple listeners that bind a click to the banner of a website and dispatch an event to Personalization.
The following are namespace-specific examples of listeners that capture email addresses using a custom callback function.
Resolvers return functions so that they can be invoked after a page has been matched. When used in a PageConfig
, the returned functions do not need to be invoked to get the final value - the underlying sitemap code handles that logic.
transform
functions are callbacks designed to evaluate or modify the resolved value.
Returns the text of the first instance of the selector in the DOM.
Returns the text of all instances of the selector in the DOM in an array.
Returns the attribute of the first instance of the selector in the DOM.
Returns the attributes of all instances of the selector in the DOM as an array.
Returns the content of the first meta tag with the given meta tag name.
Returns the content of the first itemProp
with the given itemProp
.
Returns the value from a nested object. Returns null
if the nested object, or some object in the path, does not exist.
If the path is null
, the first JSON-LD script is returned after being parsed into a JavaScript object. If a path is provided, then the value of the path from the parsed JavaScript object is returned.
Returns a pipe-delimited string using the text of all instances of the selector.
Returns a pipe-delimited string using the given attribute of all instances of the selector.
Returns a canonical URL, if one exists on the page.
Returns the value stored in window.location.href
The Personalization module of the Salesforce Interactions SDK provides several utility functions that you can use to help parse data.
The following table describes these utility functions in detail.
Utility Function | Description | Namespace |
---|---|---|
buildLineItemFromPageState(quantitySelector: string) => LineItem | Returns a LineItem constructed from the data already captured on the page, using the given quantitySelector to determine how many of the items are in the lineItem . | Both |
extractFirstGroup(regex: RegExp, str: string) => string | Returns a string of the first group extracted from the provided regex. | Both |
getFloatValue(text: string) => number | Returns a floating point number parsed from the provided string. | Evergage |
getIntegerValue(text: string) => number | Returns an integer number parsed from the provided string. | Evergage |
getLastPathComponent(url: string) => string | Returns the last path component for the provided URL. For example, SalesforceInteractions.util.getLastPathComponent("https://example.example/myExamplePath.html") returns myExamplePath.html . | Evergage |
getLastPathComponentWithoutExtension(url: string) => string | Returns the last path component without an extension for the provided URL. For example, SalesforceInteractions.util.getLastPathComponent("https://example.example/myExamplePath.html") returns myExamplePath . | Both |
getParameterByName(name: string, url?: string) => string | Returns the value of the provided parameter name from the provided URL. If no URL is provided, the current location.search of the page is used. | Both |
getPathname(url: string) => string | Returns the Pathname of the provided URL. | Evergage |
getUtagFirstForField(fieldName: string) => any | Returns the first value for the provided field in a window.utag_data object. | Evergage |
getValueFromNestedObject(path: string, obj?: object) => any | Returns the value from a nested object. If an object is not provided, window is used. Returns null if the nested object, or some object in the path, does not exist. | Both |
qualifyUrl(unqualified: string) => string | Returns a qualified URL href from an unqualified relative URL path. If unqualified is null or unprovided, returns null. | Evergage |
removeQueryString(url: string) => string | Returns a URL without query strings from the provided URL. | Evergage |
resolveWhenTrue.bind(trueFunc: () => any, bindId?: string, timeout?: number, checkInterval?: number) => Promise<any> | Returns a Promise that resolves when the provided trueFunc evaluates to true .DONE If timeout is not provided, a 2000-ms default timeout is used. If checkInterval is not provided, a 100-ms default interval is used to check the trueFunc. If the timeout is reached, the check is unbound. An unbind function is provided under resolveWhenTrue.getBindings() . If a bindId is provided, the unbind function is mapped to that key, otherwise a new random key is used. | Both |
resolveWhenTrue.unbind(bindId: string) => void | When given a bindId unbinds that bound resolveWhenTrue function. | Both |
resolveWhenTrue.getBindings() => [key: string]: unbindFunction: () | Returns a map of currently bound resolveWhenTrue functions. | Both |
resolveWhenTrue.clearBindings() => void | Clears all currently bound resolveWhenTrue functions. | Both |
Depending on the SDK namespace you're using, use either of the following code snippets to reinitialize the beacon and the Sitemap when using Personalization on a single-page application (SPA).
Executing the preceding code results in the following.
- Depending on the SDK namespace you're using, dispatch a
SalesforceInteractions.CustomEvents.OnInit
or anEvergage.CustomEvents.OnInit
event. - Reinitialize the beacon with the same settings as the initial page load (for example,
cookieDomain
). - Rerun the sitemap using the same configuration as the initial page load.
- Send activity timing for the previous page.
- Start activity timers for the current page.
Ensure that you wrap the reinitialization function in logic to determine when to reinitialize the beacon and sitemap. The following is a sample sitemap code that includes logic to reinitialize the beacon and sitemap when the URL changes without a full page load.
The following sitemap code examples are for illustrative purposes only. We recommend considering other ways of using the reinitialization function that better suits your specific use case, and the way your site functions.
The localization setting enables a single dataset to cater to a site with multiple languages and locales while leveraging the same catalog and sitemap across those languages and locales. The use of localization requires sending the locale attribute in an event.
To use catalog localizations, you must check the Enable Localization of Catalog Metadata Based on Page Locale setting in a catalog's settings via the Personalization UI by navigating to Settings > Catalog and Profile Objects.
Locales must be set in a specific format of an ISO 639 alpha-2 language code, followed by an underscore, followed by an ISO 3166 alpha-2 country code. The following list contains examples of valid locales.
en_US
en_AU
en_CA
zh_CN
en_GB
pt_PT
en_HK
zh_HK
The following is an example of a View Item event that depicts how to send an event with a locale. You can set the locale on the global
, pageTypeDefault
, and individual pageTypes
configurations in the SiteMapConfig
. You can set the locale manually in events tracked through sendEvent
functions.
When building catalog configurations in a sitemap, different locales can all use the same configuration. Localized attributes are all on the same item in Personalization. Therefore, when selecting which _id
to use for a Catalog Item, or a Catalog Item's related catalog objects, ensure that you select an _id
that does not change depending on the page's locale. Failing to do so creates extra Catalog Items and related catalog objects in the catalog and split attribution for users between different site locales. All item types can be localized.
For products, ensure that currency
, if available, is captured in the catalog along with price
. The currency
attribute takes an ISO 4217 3-character string currency code as its value and can change based on locale.
The following are example catalog
objects with a currency
attribute specified.
The following list contains examples of valid currencies.
USD
AUD
THB
EUR
BRL
DKK
When creating an order configuration on a dataset that includes locales, an additional field in the order configuration is required to calculate total revenue correctly. The currency
attribute takes an ISO 4217 3-character string currency code as its value. If no currency is provided, the default currency on the dataset is applied as the currency for items in the order
object.
The following are example order
objects with a currency
attribute specified.