A SiteMapConfig in Salesforce Personalization (formerly known as Interaction Studio) consists of three main configurations that help define how pages on a website are monitored and handled for personalized interactions. Here’s a breakdown of each section:
The global configuration applies to all pages on the website, regardless of the specific type of page. It defines objects or actions that should be monitored on every page. This could include elements such as user attributes (e.g., logged-in user info) or general interactions (e.g., clicks on certain buttons).
Purpose: To ensure certain key data points or events are captured consistently across the entire site.
Example: Tracking user login or capturing the email address from a common header section on every page.
The pageTypes configuration is used to define specific types of pages on the website, each with its own unique set of objects or interactions to monitor. You can think of it as defining a "page template" that only applies when certain conditions are met (e.g., the page’s URL contains /search for a search results page).
Purpose: To capture interactions specific to certain pages, like monitoring search terms on a search results page or preferences on a settings page.
Example: Defining a "search" page type to capture what a user searches for and recording it as part of the user’s profile.
The pageTypeDefault configuration acts as a fallback. It applies when none of the defined pageTypes match the current page. This ensures that even pages that don’t explicitly match any of the pageTypes still have a baseline configuration applied.
Purpose: To ensure that some level of monitoring and interaction is captured, even if a specific page type wasn’t defined for that page.
Note: This fallback will only work if the sitemap has at least one valid pageTypes configuration.
Example: If no specific page type matches, the default configuration might capture basic user interactions like scrolling or clicks.
The global configuration captures universal events across all pages.
The pageTypes configuration is tailored to specific pages based on conditions (like URL patterns).
The pageTypeDefault configuration is a fallback to ensure monitoring is still in place if no pageTypes conditions are met.
In Salesforce Personalization (or Evergage), the SiteMapConfig defines how different configurations are processed when a page on the site matches either a specific PageConfig (within the pageTypes array) or the pageTypeDefault. Here's a simple breakdown of how this processing and merging work:
When a page is accessed:
Match Determination: The system checks whether the page matches any specific PageConfig defined in the pageTypes array. If no match is found, it checks the pageTypeDefault as a fallback.
Merging with Global Configuration: If a match is found (either in pageTypes or pageTypeDefault), the matched configuration is merged with the settings in the global configuration.
Attribute Handling: Different attributes within the matched PageConfig and global configuration are merged in specific ways. This is crucial to ensure that settings from both levels work together without conflict.
locale:
The locale from the matched PageConfig or pageTypeDefault overrides the locale from the global configuration.
Precedence: Matched PageConfig > global locale.
contentZones:
The contentZones from both the matched PageConfig (or pageTypeDefault) and the global configuration are concatenated. This means both sets of contentZones are combined together, so no data is lost.
Example: If global has contentZones: ["header", "footer"] and the matched PageConfig has contentZones: ["sidebar"], the final result will be ["header", "footer", "sidebar"].
listeners:
Similar to contentZones, the listeners from both the matched PageConfig and global configuration are concatenated. All event listeners from both levels are retained and executed.
Example: If global has a listener for a form submission, and the matched PageConfig has a listener for a click event, both listeners will be present.
onActionEvent:
The onActionEvent functions from both the matched PageConfig and global configuration are executed, but the matched PageConfig's function runs first. After it finishes, the onActionEvent from the global configuration is executed.
Order: Matched PageConfig onActionEvent > global onActionEvent.
After all of these attributes are merged, the system evaluates the combined result and applies it to the page. So, the page will behave based on the merged configuration that includes both the general (global) rules and the specific rules for that page type.
Here’s how the configuration structure looks in JSON-like format:
{
global: GlobalConfig, // Configuration that applies to all pages
pageTypeDefault: DefaultPageConfig, // Configuration that applies when no specific page type matches
pageTypes: PageConfig[] // Array of configurations for different page types
}
This object represents a configuration that defines additional data to be tracked for specific pages.
It's used in conjunction with PageConfig or DefaultPageConfig objects to provide context-specific tracking information.
{
locale?: string | () => string,
contentZones?: ContentZone[],
listeners?: Listener[],
onActionEvent?: (event: ActionEvent) => ActionEvent
}
Properties:
locale:
Optional property that specifies the locale (language and region) for the current page.
It can be either a string value directly representing the locale (e.g., "en-US") or a function that dynamically determines the locale based on the page's context.
contentZones:
Optional array of ContentZone objects.
Each ContentZone defines a specific area or element on the page that you want to track.
It allows you to associate different tracking behaviors or data with different parts of the page.
listeners:
Optional array of Listener objects.
Each Listener specifies an event type and a callback function to be executed when that event occurs on the page.
This enables you to capture user interactions or other page events for tracking purposes.
onActionEvent:
Optional function that is called when an ActionEvent occurs on the page.
An ActionEvent represents a specific user action or interaction with the page, such as a button click or form submission.
The function can be used to process the event data, log it, or trigger other actions based on the event.
const siteMapConfig = {
globalConfig: {
locale: "en-US",
contentZones: [
{ id: "header", selector: ".header-container", // ... other content zone properties },
{ id: "footer", selector: ".footer-container", // ... other content zone properties }
],
listeners: [
{
type: "click",
selector: ".primary-button",
callback: (event) => { // Log button click event console.log("Primary button clicked:", event); }
}
],
onActionEvent: (event) => {
// Process action event (e.g., track form submission)
if (event.type === "formSubmit") { // ... track form submission data }
}
}
};
The concept of Page Types in Salesforce Personalization (or Evergage) refers to classifying different types of pages on your website, so you can apply specific tracking, personalization, and event-handling logic. Here’s a breakdown of how Page Types and the associated PageConfig work:
A Page Type is a way to categorize various pages on your website based on their functionality and URL structure. For example:
A Home page is a unique page type because there’s only one home page on a site.
A Product Display Page (PDP) is a page type that applies to many different product pages, but they share the same structure and behavior.
By defining different Page Types, you can track user interactions, capture specific data, and implement personalization based on the page they are visiting.
Page Type Configurations are set up using a pageTypes array. Each configuration object in this array contains several key properties that help the system detect which page type is currently being viewed and define specific actions for that page.
Here are the required fields for a PageConfig object:
name:
A string that names the page type (e.g., "home", "productDisplayPage").
This helps you identify the page type in your configuration.
isMatch:
A function (either synchronous or asynchronous) that returns true if the page matches the defined page type.
For example, for a product display page, the function might check if the URL path contains /product/.
Example:
isMatch: () => /\/product\//.test(window.location.pathname),
This function can also return a promise for more complex matching logic.
locale: (optional)
A string or function that defines the locale (e.g., language or region) for the page.
This helps tailor the content for specific locales.
interaction: (optional)
Defines a specific Interaction that is tracked on this page.
This could be any event you want to capture, such as product views, category views, or other page interactions.
contentZones: (optional)
An array of ContentZone objects that represent different sections of the page that can be personalized (e.g., banners, sidebars, or specific divs on the page).
This allows you to dynamically personalize key areas of the page.
listeners: (optional)
An array of Listener objects to detect and handle specific user actions, such as clicks, form submissions, or "add to cart" events.
This allows you to set up custom tracking for actions that are important for that page type.
onActionEvent: (optional)
A function that processes the event before it’s sent to Salesforce Personalization.
You can modify or enhance the event here, such as adding user or product data.
Here’s how a PageConfig might look for a product display page:
{
name: "productDisplayPage", // The name of the page type
isMatch: () => /\/product\//.test(window.location.pathname), // Detects if the URL matches a product page
locale: () => document.documentElement.lang || "en-US", // Sets the locale based on the page’s language
interaction: { name: "Product View" }, // Tracks the interaction as a product view
contentZones: [
{ name: "productDetail" }, // Content zone for the product details section
{ name: "recommendations" } // Content zone for personalized product recommendations
],
listeners: [
SalesforceInteractions.listener("click", ".add-to-cart", () => {
// Custom logic to track "Add to Cart" events
const productId = document.querySelector(".product-id").textContent;
SalesforceInteractions.sendEvent({
interaction: { name: "Add to Cart" },
user: { identities: { productId } }
});
})
],
onActionEvent: (actionEvent) => {
// Modify the event before it is sent
const productId = document.querySelector(".product-id").textContent;
actionEvent.user = actionEvent.user || {};
actionEvent.user.attributes = actionEvent.user.attributes || {};
actionEvent.user.attributes.lastViewedProduct = productId;
return actionEvent;
}
}
name: Identifies the page type for reporting or tracking purposes.
isMatch: This is crucial as it defines the logic to match a specific page type based on URL structure or other page characteristics.
locale: Sets the locale for the page if needed (optional).
interaction: Tracks specific events like product views, category views, etc. (optional).
contentZones: Defines areas on the page that can be personalized (optional).
listeners: Sets up event listeners for actions like button clicks or form submissions.
onActionEvent: Modifies the captured event data before sending it to the server (optional).
Default Page Config
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.
SalesforceInteractions Namespace
{
name: string, // required
locale?: string | () => string,
contentZones?: ContentZone[],
listeners?: Listener[],
onActionEvent?: (event: ActionEvent) => ActionEvent
}
Different types of Interactions used in the Salesforce Personalization SDK (formerly known as Interaction Studio) to track and record user activities on a webpage. These interactions allow you to track catalog objects, cart-related actions, and orders placed by users on your website.
Interaction: Represents a basic user action on the page, such as viewing a product or interacting with a page element. The main field is the name, which is required.
CatalogObjectInteraction: Extends Interaction and tracks catalog items (like products). It includes details like the type, ID, and attributes of the catalog object.
CartInteraction: Also extends Interaction and is used to track actions related to a cart, such as adding or removing items. It includes information about LineItems in the cart.
OrderInteraction: Represents a purchase order and extends Interaction. It tracks order details such as line items, total value, and any additional attributes.
These different interactions are designed to capture user activities specific to a site’s e-commerce functions, such as viewing products, adding them to the cart, and checking out.
CatalogObjectInteraction
This tracks when a user interacts with a specific catalog object, like a product.
// Catalog Object Interaction for viewing a product (hardcoded version)
const catalogInteraction = {
name: SalesforceInteractions.CatalogObjectInteractionName.ViewCatalogObjectDetail, // Action: viewing a catalog object
catalogObject: {
type: "Product", // The type of catalog object (in this case, "Product")
id: "product_123", // Hardcoded product ID
attributes: { // Hardcoded attributes of the product
sku: {
id: "sku_456", // Hardcoded SKU ID for the product
},
name: "Sample Product Name", // Hardcoded product name
description: "This is a sample short description of the product.", // Hardcoded short description of the product
url: "https://example.com/product/sample-product", // Hardcoded URL of the product page
imageUrl: "https://example.com/images/sample-product.jpg", // Hardcoded URL of the product image
inventoryCount: 1, // Hardcoded inventory count (number of products in stock)
price: 99.99, // Hardcoded price of the product (as a number)
rating: 4.5, // Hardcoded rating value (e.g., 4.5 stars)
},
// Related catalog objects such as categories, gender, color, and features
relatedCatalogObjects: {
Category: ["Electronics"], // Hardcoded related category (e.g., "Electronics")
Gender: ["MEN"], // Hardcoded gender (could be "MEN", "WOMEN", or undefined)
Color: ["Red", "Blue"], // Hardcoded colors for the product
Feature: ["WATERPROOF", "WIRELESS"], // Hardcoded features of the product (uppercased)
},
},
};
// Send this interaction to Salesforce Personalization
SalesforceInteractions.sendEvent({
interaction: catalogInteraction
});
Interaction Name:
name: SalesforceInteractions.CatalogObjectInteractionName.ViewCatalogObjectDetail: This specifies that the user interaction is viewing a catalog object, specifically a product.
Catalog Object:
type: "Product": This defines the catalog object type as a "Product".
id: "product_123": A hardcoded product ID is provided. In the original code, it dynamically resolves the ID from the webpage, but here it's set as "product_123" for simplicity.
Attributes:
sku: { id: "sku_456" }: The SKU (Stock Keeping Unit) is a unique identifier for the product variant, hardcoded here as "sku_456".
name: "Sample Product Name": The product name is hardcoded as "Sample Product Name".
description: "This is a sample short description of the product.": A hardcoded short description of the product.
url: "https://example.com/product/sample-product": The URL where the product can be found, hardcoded here.
imageUrl: "https://example.com/images/sample-product.jpg": The product image URL, hardcoded as an absolute URL.
inventoryCount: 1: The hardcoded number of items in stock.
price: 99.99: The hardcoded price of the product as a number (e.g., $99.99).
rating: 4.5: A hardcoded product rating (e.g., 4.5 stars).
Related Catalog Objects:
Category: ["Electronics"]: The product belongs to the "Electronics" category, hardcoded here.
Gender: ["MEN"]: The product is targeted at men, hardcoded as "MEN". It could also be "WOMEN", depending on the product.
Color: ["Red", "Blue"]: The product comes in "Red" and "Blue" colors, hardcoded here.
Feature: ["WATERPROOF", "WIRELESS"]: The product has two features, "WATERPROOF" and "WIRELESS", hardcoded and uppercased.
When displaying multiple products in a grid/list view, such as a search results page or a category page, the ViewCatalogObject interaction is used for each product the customer sees. However, this doesn't mean you send the data for one single product. Instead, you track each product separately as the user scrolls or views them.
Here’s how you can handle this in practice:
When a customer lands on a page that displays a list of products, like a category or search results page, you need to send a separate event for each product that is visible to the customer on that page. You do not send a single event for the entire page but rather one event for each product in the list/grid.
How to Implement it:
You can loop through each product displayed on the page and send individual ViewCatalogObject events for each product.
Here’s how you can approach this using JavaScript:
Let’s assume you have a grid of products where each product has a unique ID, name, price, and category.
// Loop through each product displayed on the page
SalesforceInteractions.cashDom(".product-item").each(function(index, productElement) {
// Extract necessary product information from each element
const productId = SalesforceInteractions.cashDom(productElement).attr("data-product-id");
const productName = SalesforceInteractions.cashDom(productElement).find(".product-name").text();
const productPrice = SalesforceInteractions.cashDom(productElement).find(".product-price").text();
const productImage = SalesforceInteractions.cashDom(productElement).find(".product-image").attr("src");
const productCategory = SalesforceInteractions.cashDom(productElement).find(".product-category").text();
// Send the ViewCatalogObject event for each product
SalesforceInteractions.sendEvent({
interaction: {
name: SalesforceInteractions.CatalogObjectInteractionName.ViewCatalogObject,
catalogObject: {
type: "Product", // Object type is a product
id: productId, // Unique product ID for each product in the list
attributes: {
name: productName, // Product name
price: parseFloat(productPrice.replace(/[^0-9\.]+/g, "")), // Price shown in catalog view
imageUrl: productImage, // Image URL shown in the catalog
},
relatedCatalogObjects: {
Category: [productCategory] // Category of the product
}
}
}
});
});
If your website has traditional pagination (like page numbers), you can trigger the ViewCatalogObject code when a user navigates to a new page. Typically, you'd attach this to the event when the next set of products is loaded.
// Attach an event listener for pagination (assuming your site uses a class like `.pagination-link`)
SalesforceInteractions.cashDom(".pagination-link").on("click", function() {
// Trigger the code after new products are loaded
// Add a small delay if necessary to ensure products are fully loaded
setTimeout(function() {
// Now repeat the same loop for each product on the new page
SalesforceInteractions.cashDom(".product-item").each(function(index, productElement) {
const productId = SalesforceInteractions.cashDom(productElement).attr("data-product-id");
const productName = SalesforceInteractions.cashDom(productElement).find(".product-name").text();
const productPrice = SalesforceInteractions.cashDom(productElement).find(".product-price").text();
const productImage = SalesforceInteractions.cashDom(productElement).find(".product-image").attr("src");
const productCategory = SalesforceInteractions.cashDom(productElement).find(".product-category").text();
SalesforceInteractions.sendEvent({
interaction: {
name: SalesforceInteractions.CatalogObjectInteractionName.ViewCatalogObject,
catalogObject: {
type: "Product",
id: productId,
attributes: {
name: productName,
price: parseFloat(productPrice.replace(/[^0-9\.]+/g, "")),
imageUrl: productImage,
},
relatedCatalogObjects: {
Category: [productCategory]
}
}
}
});
});
}, 500); // Adjust the delay based on page load time
});
For infinite scroll, products load automatically when the user reaches a certain scroll point on the page. You’ll need to listen for new products being added to the DOM and trigger the ViewCatalogObject event when they appear.
You can use MutationObserver to detect when new elements (i.e., products) are added to the page:
// Define a MutationObserver to monitor when new products are added to the DOM
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
// Check if new product elements are added
mutation.addedNodes.forEach(function(addedNode) {
if (SalesforceInteractions.cashDom(addedNode).hasClass("product-item")) {
// Extract necessary product information
const productId = SalesforceInteractions.cashDom(addedNode).attr("data-product-id");
const productName = SalesforceInteractions.cashDom(addedNode).find(".product-name").text();
const productPrice = SalesforceInteractions.cashDom(addedNode).find(".product-price").text();
const productImage = SalesforceInteractions.cashDom(addedNode).find(".product-image").attr("src");
const productCategory = SalesforceInteractions.cashDom(addedNode).find(".product-category").text();
// Send the ViewCatalogObject event for the new product
SalesforceInteractions.sendEvent({
interaction: {
name: SalesforceInteractions.CatalogObjectInteractionName.ViewCatalogObject,
catalogObject: {
type: "Product",
id: productId,
attributes: {
name: productName,
price: parseFloat(productPrice.replace(/[^0-9\.]+/g, "")),
imageUrl: productImage,
},
relatedCatalogObjects: {
Category: [productCategory]
}
}
}
});
}
});
});
});
// Observe the container that holds the product list for new additions
observer.observe(document.querySelector('.product-grid'), {
childList: true, // Detect when new child nodes (products) are added
subtree: true, // Monitor all descendants of the container
});
the difference between SalesforceInteractions.CartInteractionName.AddToCart and SalesforceInteractions.CartInteractionName.ReplaceCart, and go over their usage with examples.
The AddToCart interaction is used when a customer adds an item to their shopping cart. This interaction is fired specifically when a new item is added to the existing cart. It does not modify the existing cart items; it only appends the new item to the cart.
Example:
The following code listens for a user clicking the "Add to Cart" button, extracts the relevant product information (such as quantity), and sends the AddToCart event for that specific item.
SalesforceInteractions.listener("click", ".add-to-cart", () => {
// Build the line item from the current page state, i.e., the product selected by the user
let lineItem = SalesforceInteractions.mcis.buildLineItemFromPageState(
"select.quantity-select option:checked", // Selector to get the selected quantity
);
// Send the 'AddToCart' event for this line item
SalesforceInteractions.sendEvent({
interaction: {
name: SalesforceInteractions.CartInteractionName.AddToCart, // Add to cart interaction
lineItem: lineItem, // The product and its details
},
});
});
Key Points:
The event is fired when the user clicks the "Add to Cart" button.
It only adds one product (or a specific variation of a product) to the cart at a time.
This interaction is common in product detail pages (PDP) or quick views where users click a button to add individual products.
The ReplaceCart interaction is fired when the entire shopping cart is replaced or updated with a new set of items. This typically happens when the cart is loaded or refreshed (such as when a user visits the cart page), or when multiple products and quantities in the cart are updated all at once.
Example:
The code below is for use on the cart page, where all the products currently in the cart are extracted and the ReplaceCart event is fired. This sends the entire set of items (or "line items") currently in the cart to Salesforce for tracking.
{
name: "cart",
isMatch: () => /\/cart/.test(window.location.href), // Check if the current page is the cart page
interaction: {
name: SalesforceInteractions.CartInteractionName.ReplaceCart, // Replace cart interaction
lineItems: SalesforceInteractions.DisplayUtils.pageElementLoaded(
".cart-empty, .checkout-btn", // Wait until the cart is fully loaded or visible
"html",
).then(() => {
let cartLineItems = [];
// Loop through each product in the cart
SalesforceInteractions.cashDom(".product-info .product-details").each((index, ele) => {
let itemQuantity = parseInt(
SalesforceInteractions.cashDom(ele).find(".qty-card-quantity-count").text().trim(),
);
// Only add items that have a quantity greater than 0
if (itemQuantity && itemQuantity > 0) {
let lineItem = {
catalogObjectType: "Product", // Object type is a product
catalogObjectId: SalesforceInteractions.cashDom(ele)
.find(".line-item-quantity-info")
.attr("data-pid")
.trim(), // Product ID
price:
SalesforceInteractions.cashDom(ele)
.find(".pricing")
.text()
.trim()
.replace(/[^0-9\.]+/g, "") / itemQuantity, // Price per item
quantity: itemQuantity, // Quantity of the product in the cart
};
cartLineItems.push(lineItem);
}
});
return cartLineItems; // Return the array of cart items to be sent
}),
},
}
Key Points:
This event is triggered when the user views or updates their cart.
It collects all the items currently in the cart (not just one item like AddToCart).
It's usually fired on the cart page or when a cart is dynamically updated (such as a bulk update of quantities).
Each product in the cart is sent as a line item with its details (quantity, price, etc.).
When to Use AddToCart vs. ReplaceCart:
AddToCart Example:
The user clicks on "Add to Cart" for a product on the product detail page or from a product grid.
This interaction tracks that one specific product has been added to the cart.
ReplaceCart Example:
The user navigates to the cart page, and the script extracts all the products currently in the cart (line items) and fires the ReplaceCart interaction.
This tracks the entire cart, including all products, their quantities, and their prices.
The SalesforceInteractions.OrderInteractionName.Purchase is typically used to track when a customer completes a purchase and the order is confirmed. This interaction captures the details of the order, including the order ID, line items (products), prices, and quantities, and sends this data to Salesforce.
Let's break down the example provided, and then I'll explain the value of lineItems.
In this example, the interaction is triggered when the user reaches the order confirmation page (usually after completing a checkout). The interaction captures the entire order and its details, such as the order number and products purchased.
Example Breakdown:
{
name: "order_confirmation", // Name of the page or interaction
isMatch: () => /\/confirmation/.test(window.location.href), // Trigger when the URL matches the order confirmation page
interaction: {
name: SalesforceInteractions.OrderInteractionName.Purchase, // This specifies the Purchase interaction
order: {
// Fetch the order ID from the order confirmation page
id: SalesforceInteractions.DisplayUtils.pageElementLoaded(".order-number", "html").then(
(ele) => {
return SalesforceInteractions.resolvers.fromSelector(".order-number"); // Resolves the order number from the page
},
),
// Fetch the line items (products) from the order confirmation page
lineItems: SalesforceInteractions.DisplayUtils.pageElementLoaded(
".product-line-item", // Wait for the product line items to load
"html",
).then(() => {
let purchaseLineItems = [];
// Loop through each product in the order confirmation page
SalesforceInteractions.cashDom(".product-line-item").each((index, ele) => {
let itemQuantity = parseInt(
SalesforceInteractions.cashDom(ele).find(".qty-card-quantity-count").text().trim(),
);
// Ensure that the product has a quantity greater than 0 before adding it to the lineItems array
if (itemQuantity && itemQuantity > 0) {
let lineItem = {
catalogObjectType: "Product", // The type of catalog object, in this case, it is a product
catalogObjectId: SalesforceInteractions.cashDom(ele)
.find(".line-item-quantity-info")
.attr("data-pid")
.trim(), // The unique ID of the product purchased
price:
SalesforceInteractions.cashDom(ele)
.find(".pricing")
.text()
.trim()
.replace(/[^0-9\.]+/g, "") / itemQuantity, // The price per item (total price divided by quantity)
quantity: itemQuantity, // The quantity of this product purchased
};
// Add the lineItem object to the purchaseLineItems array
purchaseLineItems.push(lineItem);
}
});
// Return the array of line items (products) purchased
return purchaseLineItems;
}),
},
},
}
isMatch():
This function checks whether the current URL contains /confirmation. It ensures that the interaction is only triggered on the order confirmation page.
name: SalesforceInteractions.OrderInteractionName.Purchase:
This specifies that the interaction being sent is related to a purchase (i.e., the customer has completed their order).
order: {}:
This section captures the details of the order. It includes two important pieces of information:
Order ID:
The id is resolved from the order confirmation page by selecting the element that contains the order number (e.g., .order-number).
Line Items:
The lineItems array contains all the products that the customer purchased, including their quantities and prices.
The lineItems array contains objects representing each product in the order. Each line item consists of the following details:
catalogObjectType: "Product":
This indicates that the catalog object is a product. It could be other types for different objects, but for purchases, it is typically "Product".
catalogObjectId:
This is the unique identifier (ID) of the product purchased. In this case, it's being fetched from the data-pid attribute on the product element.
price:
The price of the product. Here, it's divided by the quantity to get the price per item.
quantity:
The number of units of the product purchased.
Example of a line item:
javascript
Copy code
{
catalogObjectType: "Product",
catalogObjectId: "12345", // Product ID
price: 50.00, // Price per item
quantity: 2, // Number of items purchased
}
If the customer bought two products with IDs "12345" and "67890", the lineItems array might look like:
javascript
Copy code
[
{
catalogObjectType: "Product",
catalogObjectId: "12345",
price: 50.00,
quantity: 2,
},
{
catalogObjectType: "Product",
catalogObjectId: "67890",
price: 100.00,
quantity: 1,
}
]
Order ID: The unique identifier of the order (e.g., ORDER123).
Line Items: An array of products, including the product ID, price, and quantity.
This interaction will allow Salesforce to track the entire purchase for that order, including all products and their quantities.
Cart Interactions (AddToCart, ReplaceCart):
These are used to track items that are added to or modified in the shopping cart before checkout.
Purchase Interaction (Purchase):
This is used to track completed orders. It captures the final details of the purchase after the user has gone through checkout.
A customer visits your eCommerce site and adds items to their cart (tracked via AddToCart).
They proceed to checkout and confirm their order.
Once the customer lands on the order confirmation page, the Purchase interaction is triggered, and Salesforce captures the order details (order ID, products, prices, quantities).
Let me know if this clarifies the use of the Purchase interaction or if you need further details!