Sample Ecommerce Sitemap
Review this sample sitemap.
Ecommerce Sitemap Example
1SalesforceInteractions.init({
2 consents: new Promise((resolve) => {
3 const { OptIn, OptOut } = SalesforceInteractions.ConsentStatus;
4 const purpose = SalesforceInteractions.ConsentPurpose.Tracking;
5 const provider = "Test Provider";
6
7 // user clicks button that grants consent
8 document
9 .getElementById("opt-in")
10 .addEventListener("click", () => resolve([{ purpose, provider, status: OptIn }]), {
11 once: true,
12 });
13
14 // user clicks button that revokes consent
15 document
16 .getElementById("opt-out")
17 .addEventListener("click", () => resolve([{ purpose, provider, status: OptOut }]), {
18 once: true,
19 });
20 }),
21}).then(() => {
22 // set the log level during sitemap development to see potential problems
23 SalesforceInteractions.log.level = "debug";
24
25 const {
26 cashDom,
27 listener,
28 resolvers,
29 sendEvent,
30 util,
31 CartInteractionName,
32 CatalogObjectInteractionName,
33 OrderInteractionName,
34 } = SalesforceInteractions;
35
36 const global = {
37 listeners: [
38 // capture email address when a user signs up
39 listener("submit", ".user-signup-form", (actionEvent) => {
40 const emailAddress = cashDom("#user_email").val();
41 if (emailAddress) {
42 sendEvent({
43 interaction: {
44 name: "Email Sign Up",
45 },
46 user: {
47 attributes: {
48 email: emailAddress,
49 eventType: "contactPointEmail",
50 },
51 },
52 });
53 }
54 }),
55 ],
56
57 // attach optional data to every actionEvent that is sent out
58 onActionEvent: (actionEvent) => {
59 const email = window && window._userInfo && window._userInfo.email;
60 if (email) {
61 actionEvent.user = actionEvent.user || {};
62 actionEvent.user.attributes = actionEvent.user.attributes || {};
63 actionEvent.user.attributes.emailAddress = email;
64 }
65 return actionEvent;
66 },
67 };
68
69 const productIdResolver = resolvers.fromSelectorAttribute(".product", "data-id");
70
71 const productPage = {
72 name: "product",
73 isMatch: () => /products/.test(window.location.pathname),
74 // capture the product being viewed when the page is opened
75 interaction: {
76 name: CatalogObjectInteractionName.ViewCatalogObject,
77 catalogObject: {
78 type: "Product",
79 id: productIdResolver,
80 attributes: {
81 name: resolvers.fromSelector(".product-title"),
82 url: resolvers.fromHref(),
83 imageUrl: resolvers.fromSelectorAttribute(".product img", "src"),
84 },
85 relatedCatalogObjects: {
86 Color: resolvers.fromSelectorAttributeMultiple(".color-value", "data-attr-value"),
87 },
88 },
89 },
90 listeners: [
91 // capture when the user adds this product to their cart
92 listener("click", ".add-to-cart", () => {
93 sendEvent({
94 interaction: {
95 name: CartInteractionName.AddToCart,
96 lineItem: {
97 catalogObjectType: "Product",
98 catalogObjectId: productIdResolver(),
99 quantity: parseInt(cashDom(".product .quantity input").val(), 10),
100 price: parseFloat(cashDom(".product .price").text().trim()),
101 },
102 },
103 });
104 }),
105 // capture when the user shares the product to social media
106 listener("click", ".share", () => {
107 sendEvent({
108 interaction: {
109 name: CatalogObjectInteractionName.ShareCatalogObject,
110 catalogObject: {
111 type: "Product",
112 id: productIdResolver(),
113 },
114 },
115 });
116 }),
117 ],
118 };
119
120 const cartPage = {
121 name: "Cart",
122 isMatch: () => /^\/cart/.test(window.location.href),
123 listeners: [
124 // capture when a user removes an item from their cart
125 listener("click", ".remove-from-cart", (event) => {
126 const $cartItem = cashDom(event.target).parents(".cart-item").first();
127 sendEvent({
128 interaction: {
129 name: CartInteractionName.RemoveFromCart,
130 lineItem: {
131 catalogObjectType: "Product",
132 catalogObjectId: $cartItem.attr("data-id"),
133 quantity: parseInt($cartItem.find(".quantity").text().trim(), 10),
134 },
135 },
136 });
137 }),
138 ],
139 };
140
141 const orderConfirmationPage = {
142 name: "Order Configuration",
143 isMatch: /\/confirmation/.test(window.location.href),
144 // capture when a user completes an order
145 interaction: {
146 name: OrderInteractionName.Purchase,
147 order: {
148 id: resolvers.fromSelectorAttribute(".order", "data-id"),
149 totalValue: parseFloat(resolvers.fromSelector(".order .total").trim()),
150 lineItems: () =>
151 cashDom(".order .line-items").map((index, el) => {
152 const $lineItem = cashDom(el);
153 return {
154 catalogObjectType: "Product",
155 catalogObjectId: $lineItem.attr("data-id"),
156 quantity: parseInt($lineItem.find(".quantity").text().trim(), 10),
157 };
158 }),
159 },
160 },
161 };
162
163 const pageTypeDefault = {
164 name: "default",
165 };
166
167 SalesforceInteractions.initSitemap({
168 global,
169 pageTypeDefault,
170 pageTypes: [cartPage, orderConfirmationPage, productPage],
171 });
172});Sample for Profile Events
To implement profile events like Identity, ContactPointEmail, and ContactPointPhone refer to this example.
1SalesforceInteractions.listener("click", "#register", () => {
2 SalesforceInteractions.reinit();
3 const email = window.email;
4 const phone = window.phonenumber;
5 const firstname = window.firstname;
6 const lastname = window.lastname;
7
8 if (email) {
9 SalesforceInteractions.sendEvent({
10 user: {
11 attributes: {
12 email: email,
13 eventType: "contactPointEmail",
14 },
15 },
16 });
17 }
18 if (phone) {
19 SalesforceInteractions.sendEvent({
20 user: {
21 attributes: {
22 phoneNumber: phone,
23 eventType: "contactPointPhone",
24 },
25 },
26 });
27 }
28 SalesforceInteractions.sendEvent({
29 user: {
30 attributes: {
31 firstName: firstname || "",
32 lastName: lastname || "",
33 eventType: "identity",
34 isAnonymous: 0,
35 },
36 },
37 });
38});