Financial Services

The following code sample depicts sitemap code for an imaginary implementation of Marketing Cloud Personalization on the Cumulus Financial Services website https://www.cumulusfinserv.com/. This sitemap code isn’t exhaustive and maps only key areas valuable for demonstrating an example implementation of Personalization. The primary focus of this sitemap code is to depict how to approach designing a Catalog for websites offering financial services.

For financial services implementations, we recommend using the Product catalog type as showcased in this example. In order to use this catalog type, we add a default price and quantity for each Product when creating line items as that data is not typically present on financial services Product Detail Pages (PDPs). Then on the forms associated with PDPs, we create a checkout flow and fire a Purchase interaction when the last step of a form is clicked. We don’t recommend using a custom catalog object type as it doesn’t as easily allow for conversion tracking. It’s also harder to illustrate ownership when using a non-Product catalog type.

The sitemap code examples in this article are only for demonstration purposes. Avoid copying sample code into your Sitemap Editor as it is built around example scenarios that can differ from your implementation’s goals and use cases.

Important

Example Sitemap for the SalesforceInteractions Namespace 

1// This helper function is used help with the Purchase flow and returns an array of lineItems
2function handleLineItems() {
3    let itemId;
4    if (window.localStorage.getItem('lastAddToCart')) {
5        itemId = window.localStorage.getItem('lastAddToCart');
6    }
7    let purchaseLineItems = [];
8    if (itemId != null) {
9        let lineItem = {
10            catalogObjectType: "Product",
11            catalogObjectId: itemId,
12            price: 1, 
13            quantity: 1
14        };
15        purchaseLineItems.push(lineItem);
16    }
17    return purchaseLineItems;
18}
19/* 
20 * This helper function handles adds to cart, adds the last carted item to local storage,
21and sets a user attribute
22 * called "lastAddToCart". This attribute can used for campaigns or recipe purposes. 
23*/
24function handleAddToCart(){
25    let cartedItem = SalesforceInteractions.mcis.getLastPathComponentWithoutExtension(window.location.href).toUpperCase();
26    window.localStorage.setItem("lastAddToCart", cartedItem);
27    SalesforceInteractions.sendEvent({
28        user: {
29            attributes: {
30                lastAddToCart: cartedItem
31            }
32        },
33        interaction: {
34            name: SalesforceInteractions.CartInteractionName.AddToCart,
35            lineItem: {
36                catalogObjectType: "Product",
37                catalogObjectId: cartedItem,
38                price: 1,
39                quantity: 1
40            }
41        }
42    })
43}
44/* This helper function passes in data from a form interaction and converts it into a proper actionEvent.
45 * It also pulls all the possible selectors for form inputs to make sure they get scraped
46 * to the correct user attributes.
47*/
48function handleFormInteraction({ interactionName, user = {}, order = {} }) {
49    const actionEvent = {
50        user: {
51            ...user
52        },
53        interaction: {
54            name: interactionName,
55            order: {
56                ...order
57            }
58        }
59    };
60    actionEvent.user.attributes = {
61        firstName: SalesforceInteractions.cashDom("#firstName, input[name='firstName'], #form-appointment-first-name,
62         #form-advisor-first-name, #form-advisor-first-name").val(),
63        lastName: SalesforceInteractions.cashDom("#lastName, input[name='lastName'], #form-appointment-last-name,
64         #form-advisor-last-name").val(),
65        emailAddress: SalesforceInteractions.cashDom("#email, input[name='email'], #form-appointment-email,
66         #form-advisor-email").val(),
67        zipcode: SalesforceInteractions.cashDom("#zip, input[name='postal'], #form-appointment-zip, #form-advisor-zip,
68         #form-application-zip").val(),
69        existingCustomer: SalesforceInteractions.cashDom("select.form-control option[selected], #form-appointment-existing,
70         #form-advisor-existing").val(),
71        phone: SalesforceInteractions.cashDom("input[name='phone'], #form-application-phone").val(),
72        companyName: SalesforceInteractions.cashDom("#form-appointment-company-name, #form-advisor-company-name").val(),
73        over18: SalesforceInteractions.cashDom("#inlineAge:checked").val(),
74        usCitizen: SalesforceInteractions.cashDom("#inlineCitizen:checked").val(),
75        birthday: SalesforceInteractions.cashDom("#datepicker, input[name='birthday']").val(),
76        addressLine1: SalesforceInteractions.cashDom("input[name='addr1'], #form-application-address-01").val(),
77    }
78    SalesforceInteractions.sendEvent(actionEvent);
79}
80/* This helper function helps with the form_complete pageTypes so the correct interaction name
81 * is fired based on the form completed.
82*/
83function handleCompleteInteraction() {
84    if (/^\/account\-application\-complete$/.test(window.location.pathname)) {
85        return "Open an Account Form - Complete";
86    } else if (/^\/quote\-application\-complete$/.test(window.location.pathname)) {
87        return "Get A Quote Form - Complete";
88    } else if (/loan\-application\-complete/.test(window.location.pathname)) {
89        return "Pre-Approved Form - Complete";
90    } else {
91        return "Schedule Apppointment Form - Complete";
92    }
93}
94
95SalesforceInteractions.init({
96    cookieDomain: "cumulusfinserv.com",
97    consents: [{
98        purpose: SalesforceInteractions.mcis.ConsentPurpose.Personalization,
99        provider: "Example Consent Manager",
100        status: SalesforceInteractions.ConsentStatus.OptIn
101    }]
102}).then(() => {
103    const sitemapConfig = {
104        global: {
105            contentZones: [
106                { name: "global_popup"}
107            ]
108        },
109        pageTypeDefault: {
110            name: "default"
111        },
112        pageTypes: [
113            {
114                name: "personal_home",
115                isMatch: () => /^\/$/.test(window.location.pathname),
116                interaction: {
117                    name: "Personal - Homepage"
118                },
119                contentZones: [
120                    { name: "personal_home_hero", selector: ".hero-inner" },
121                    { name: "personal_home_recommendations", selector: ".intro-content" },
122                    { name: "personal_home_nav", selector: "body > div.category-menu" },
123                ]
124            },
125            {
126                name: "corporate_home",
127                isMatch: () => /^\/corporate$/.test(window.location.pathname),
128                interaction: {
129                    name: "Corporate - Homepage"
130                },
131                contentZones: [
132                    { name: "corporate_home_hero", selector: ".hero-inner" },
133                    { name: "corporate_home_recommendations", selector: ".intro-content" },
134                    { name: "corporate_home_nav", selector: "body > div.category-menu" },
135                ]
136            },
137            {
138                name: "login",
139                isMatch: () => /^\/login$/.test(window.location.pathname),
140                interaction: {
141                    name: "Login Page"
142                },
143                listeners: [
144                    SalesforceInteractions.listener("submit", ".form-signin", () => {
145                        handleFormInteraction({
146                            user: {
147                                identities: {
148                                    emailAddress: SalesforceInteractions.cashDom("inputEmail").val(),
149                                    }
150                                },
151                            interactionName: "Contact Form Submit"
152                        });
153                    })
154                ]
155            },
156            {
157                name: "contact_us",
158                isMatch: () => /^\/company\/contact\-us$/.test(window.location.pathname),
159                interaction: {
160                    name: "Contact Us"
161                },
162                listeners: [
163                    SalesforceInteractions.listener("submit", ".form-signin", () => {
164                        handleFormInteraction({
165                            user: {
166                                attributes: {
167                                    message: SalesforceInteractions.cashDom(".form-control.contact").val()
168                                }
169                            },
170                            interactionName: "Contact Form Submit"
171                        });
172
173                    })
174                ]
175            },
176            {
177                name: "pdp",
178                isMatch: () => SalesforceInteractions.cashDom("div.container.product-intro").length > 0,
179                interaction: {
180                    name: SalesforceInteractions.CatalogObjectInteractionName.ViewCatalogObject,
181                    catalogObject: {
182                        type: "Product",
183                        id: SalesforceInteractions.resolvers.fromHref((url) => url.split("/").splice(-1)[0].toUpperCase()),
184                        attributes: {
185                            name: SalesforceInteractions.resolvers.fromSelector("h1"),
186                            description: SalesforceInteractions.resolvers.fromSelector(".product-intro h3"),
187                            price: 1,
188                            url: SalesforceInteractions.resolvers.fromHref(),
189                            imageUrl: SalesforceInteractions.resolvers.fromSelectorAttribute(".img-responsive", "src"),
190                            inventoryCount: 1
191                        },
192                        relatedCatalogObjects: {
193                            Category: SalesforceInteractions.resolvers.buildCategoryId(".nav a.current span", null, null, (id) => {
194                                let topLevel = SalesforceInteractions.cashDom("li.current a").text().trim().toUpperCase();
195                                return [topLevel+"|"+id.toUpperCase()];
196                            }),
197                            ItemClass: SalesforceInteractions.resolvers.fromSelectorMultiple("li.current a"),
198                            Keyword: SalesforceInteractions.resolvers.fromMeta("keywords", (keyword) => {
199                                return [keyword];
200                            }),
201                            Benefits: SalesforceInteractions.resolvers.fromSelectorMultiple(".product-details .col-md-6:nth-of-type(1) li"),
202                            Requirements: SalesforceInteractions.resolvers.fromSelectorMultiple(".product-details .col-md-6:nth-of-type(2) li")
203                        }
204                    }
205                },
206                listeners: [
207                    SalesforceInteractions.listener("click", ".product-intro .btn.green-btn.btn-med", handleAddToCart)
208                ],
209                contentZones: [
210                    { name: "pdp_cta", selector: ".btn.green-btn.btn-med" },
211                    { name: "pdp_image", selector: ".pdp-img-responsive"}
212                ]
213            },
214            {
215                name: "Category",
216                isMatch: () => SalesforceInteractions.cashDom("div.offerings").length === 1,
217                interaction: {
218                    name: SalesforceInteractions.CatalogObjectInteractionName.ViewCatalogObject,
219                    catalogObject: {
220                        type: "Category",
221                        id: SalesforceInteractions.resolvers.buildCategoryId(".nav a.current span", null, null, (id) => {
222                            let topLevel = SalesforceInteractions.cashDom("li.current a").text().trim().toUpperCase();
223                            if (/.*\/investing\/retirement\-planning$/.test(window.location.href)) {
224                                return "PERSONAL|INVESTING|RETIREMENT PLANNING";
225                            } else {
226                                return topLevel+"|"+id.toUpperCase();
227                            }
228                        }),
229                        attributes: {
230                            name: SalesforceInteractions.resolvers.fromSelector("h1"),
231                            url: SalesforceInteractions.resolvers.fromHref(),
232                            imageUrl: SalesforceInteractions.resolvers.fromSelectorAttribute(".img-responsive", "src"),
233                        }
234                    }
235                },
236                contentZones: [
237                    { name: "category_hero_img", selector: ".svg-hero-container img" }
238                ]
239            },
240            {
241                name: "pre_approved",
242                isMatch: () => /\/get-preapproved/.test(window.location.href),
243                interaction: {
244                    name: "Pre-Approved"
245                },
246                listeners: [
247                    SalesforceInteractions.listener("click", "#form-application-01-next", () => {
248                        handleFormInteraction({
249                            interactionName: "Pre-Approved Form - Step 1 Submit",
250                        });
251                    }),
252                     SalesforceInteractions.listener("click", "#form-application-02-next", () => {
253                        handleFormInteraction({
254                            user: {
255                                attributes: {
256                                    loanAmount: SalesforceInteractions.cashDom("#form-application-loan-amount").val(),
257                                    purchasePrice: SalesforceInteractions.cashDom("#form-application-purchase-price").val(),
258                                    downPayment: SalesforceInteractions.cashDom("#form-application-down-payment").val(),
259                                    propertyType: SalesforceInteractions.cashDom("#form-application-property-type").val(),
260                                    realtorPhone: SalesforceInteractions.cashDom("#form-application-phone-number").val()
261                                }
262                            },
263                            interactionName: "Pre-Approved Form - Step 2 Submit",
264                        });
265                    }),
266                    SalesforceInteractions.listener("click", "#startJourney", () => {
267                        handleFormInteraction({
268                            interactionName: SalesforceInteractions.OrderInteractionName.Purchase,
269                            user: {
270                                attributes: {
271                                    income: SalesforceInteractions.cashDom("input[name='income']").val(),
272                                    assets: SalesforceInteractions.cashDom("input[name='assets']").val()
273                                }
274                            },
275                            order: {
276                                lineItems: handleLineItems()
277                            }
278                        })
279                    }),
280                    SalesforceInteractions.listener("click", "#msform", (event) => {
281                        if (SalesforceInteractions.cashDom(event.target).closest(".save").length > 0) {
282                            const step = SalesforceInteractions.cashDom("#progressbar .active").length;
283                            if (step > 0) {
284                                handleFormInteraction({
285                                    user: {
286                                        attributes: { accountLifecycleState: "Pre-approved Open" }
287                                    },
288                                    interactionName: "Pre-approved Form Step " + step + " Save For Later",
289                                });
290                            }
291                        }
292                    })
293                ]
294            },
295            {
296                name: "form_complete",
297                isMatch: () => /(appointment\-confirmed)|(loan\-application\-complete)|(^\/quote\-application\-complete$)
298                |(^\/account\-application\-complete$)]/.test(window.location.pathname),
299                interaction: {
300                    name: handleCompleteInteraction()
301                },
302                contentZones: [
303                    { name: "form_complete_app_wrapper", selector: ".application-wrapper" },
304                    { name: "schedule_appointment_complete_app_wrapper", selector: ".ty-white-wrapper" }
305                ]
306            },
307            {
308                name: "get_quote",
309                isMatch: () => /\/get\-a\-quote/.test(window.location.href),
310                interaction: {
311                    name: "Get A Quote"
312                },
313                listeners: [
314                    SalesforceInteractions.listener("click", "#form-application-01-next", () => {
315                        handleFormInteraction({
316                            interactionName: "Get A Quote Form - Step 1 Submit",
317                        });
318                    }),
319                     SalesforceInteractions.listener("click", "#form-application-02-next", () => {
320                        handleFormInteraction({
321                            user: {
322                                attributes: {
323                                    lastInsuranceType: SalesforceInteractions.cashDom("#insuranceType").val().toUpperCase(),
324                                }
325                            },
326                            interactionName: "Get A Quote Form - Step 2 Submit",
327                        });
328                    }),
329                    SalesforceInteractions.listener("click", "#startJourney", () => {
330                        handleFormInteraction({
331                            interactionName: SalesforceInteractions.OrderInteractionName.Purchase,
332                            order: {
333                                lineItems: handleLineItems()
334                            }
335                        })
336                    }),
337                    SalesforceInteractions.listener("click", "#msform", (event) => {
338                        if (SalesforceInteractions.cashDom(event.target).closest(".save").length > 0) {
339                            const step = SalesforceInteractions.cashDom("#progressbar .active").length;
340                            if (step > 0) {
341                                handleFormInteraction({
342                                    user: {
343                                        attributes: { accountLifecycleState: "Get A Quote Open" }
344                                    },
345                                    interactionName: "Get a Quote Form Step " + step + " Save For Later",
346                                });
347                            }
348                        }
349                    })
350                ]
351            },
352            {
353                name: "apply_creditcard",
354                isMatch: () => /\/apply\-for\-a\-card/.test(window.location.href),
355                interaction: {
356                    name: "Apply For Credit Card"
357                },
358                listeners: [
359                    SalesforceInteractions.listener("click", "fieldset:nth-of-type(1) input.next.btn.green-btn.btn-med", (event) => {
360                        handleFormInteraction({
361                            interactionName: "Apply for Credit Card Form - Step 1 Submit",
362                        });
363                    }),
364                     SalesforceInteractions.listener("click", "fieldset:nth-of-type(2) input.next.btn.green-btn.btn-med", (event) => {
365                        handleFormInteraction({
366                            user: {
367                                attributes: {
368                                    lastCCType: SalesforceInteractions.cashDom("#card option").val().toUpperCase(),
369                                }
370                            },
371                            interactionName: "Apply for Credit Card Form - Step 2 Submit",
372                        });
373                    }),
374                    SalesforceInteractions.listener("click", "fieldset:nth-of-type(3) input.next.btn.green-btn.btn-med", (event) => {
375                        handleFormInteraction({
376                            user: {
377                                attributes: {
378                                    city: SalesforceInteractions.cashDom("input[name='city']").val(),
379                                    state: SalesforceInteractions.cashDom("input[name='state']").val()
380                                }
381                            },
382                            interactionName: "Apply for Credit Card Form - Step 3 Submit",
383                        });
384                    }),
385                    SalesforceInteractions.listener("click", "#startJourney", () => {
386                        handleFormInteraction({
387                            interactionName: SalesforceInteractions.OrderInteractionName.Purchase,
388                            order: {
389                                lineItems: handleLineItems()
390                            }
391                        })
392                    }),
393                    SalesforceInteractions.listener("click", "#msform", (event) => {
394                        if (SalesforceInteractions.cashDom(event.target).closest(".save").length > 0) {
395                            const step = SalesforceInteractions.cashDom("#progressbar .active").length;
396                            if (step > 0) {
397                                handleFormInteraction({
398                                    user: {
399                                        attributes: { accountLifecycleState: "Apply for Credit Card Open" }
400                                    },
401                                    interactionName: "Apply for Credit Card Form Step " + step + " Save For Later",
402                                });
403                            }
404                        }
405                    })
406                ]
407            },
408            {
409                name: "open_account",
410                isMatch: () => /\/open\-an\-account/.test(window.location.href),
411                interaction: {
412                    name: "Open an Account"
413                },
414                listeners: [
415                    SalesforceInteractions.listener("click", "#form-application-01-next", () => {
416                        handleFormInteraction({
417                            interactionName: "Open an Account Form - Step 1 Submit",
418                        });
419                    }),
420                     SalesforceInteractions.listener("click", "#form-application-02-next", (event) => {
421                        handleFormInteraction({
422                            user: {
423                                attributes: {
424                                    lastAccountType: SalesforceInteractions.cashDom("#form-application-account-type").val().toUpperCase(),
425                                }
426                            },
427                            interactionName: "Open an Account Form - Step 2 Submit",
428                        });
429                    }),
430                    SalesforceInteractions.listener("click", "#form-application-03-next", () => {
431                        handleFormInteraction({
432                            user: {
433                                attributes: {
434                                    addressLine2: SalesforceInteractions.cashDom("#form-application-address-02").val(),
435                                    city: SalesforceInteractions.cashDom("#form-application-city").val(),
436                                    state: SalesforceInteractions.cashDom("#form-application-state").val(),
437                                }
438                            },
439                            interactionName: "Open an Account Form - Step 3 Submit",
440                        });
441                    }),
442                    SalesforceInteractions.listener("click", "#startJourney", () => {
443                        handleFormInteraction({
444                            interactionName: SalesforceInteractions.OrderInteractionName.Purchase,
445                            order: {
446                                lineItems: handleLineItems()
447                            }
448                        })
449                    }),
450                    SalesforceInteractions.listener("click", "#msform", (event) => {
451                        if (SalesforceInteractions.cashDom(event.target).closest(".save").length > 0) {
452                            const step = SalesforceInteractions.cashDom("#progressbar .active").length;
453                            if (step > 0) {
454                                handleFormInteraction({
455                                    user: {
456                                        attributes: { accountLifecycleState: "Account Application Open" }
457                                    },
458                                    interactionName: "Open an Account Form Step " + step + " Save For Later",
459                                });
460                            }
461                        }
462                    })
463                ]
464            },
465            {
466                name: "schedule_appointment",
467                isMatch: () => /\/corporate\/schedule\-appointment$/.test(window.location.href),
468                interaction: {
469                    name: "Schedule Appointment"
470                },
471                listeners: [
472                    SalesforceInteractions.listener("click", "#form-appointment-schedule-btn", () => {
473                        handleFormInteraction({
474                            interactionName: SalesforceInteractions.OrderInteractionName.Purchase,
475                            order: {
476                                lineItems: handleLineItems()
477                            },
478                            user: {
479                                attributes: {
480                                    appointmentReason: SalesforceInteractions.cashDom("#form-appointment-reason").val(),
481                                    branch: SalesforceInteractions.cashDom("#form-appointment-branch").val(),
482                                    lastApptDate: SalesforceInteractions.cashDom("#form-appointment-date").val(),
483                                    lastApptTime: SalesforceInteractions.cashDom("#form-appointment-time").val()
484                                }
485                            }
486                        })
487                    })
488                ]
489            },
490            {
491                name: "learn_more",
492                isMatch: () => /\/corporate\/learn\-more/.test(window.location.href),
493                interaction: {
494                    name: "Learn More"
495                },
496                listeners: [
497                    SalesforceInteractions.listener("click", "#form-advisor-submit-btn", () => {
498                        handleFormInteraction({
499                            interactionName: "Learn More Form - Submit",
500                            user: {
501                                attributes: {
502                                    companySize: SalesforceInteractions.cashDom("#form-advisor-company-size").val(),
503                                    industry: SalesforceInteractions.cashDom("#form-advisor-industry").val(),
504                                }
505                            }
506                        })
507                    })
508                ]
509            }
510        ]
511    };
512
513    SalesforceInteractions.initSitemap(sitemapConfig);
514});

Example Sitemap for the Evergage Namespace 

1Evergage.init().then(() => {
2  const config = {
3    global: {},
4    pageTypes: [
5      {
6        name: "home",
7        action: "Homepage",
8        isMatch: () => /^\/$/.test(window.location.pathname),
9        contentZones: [
10          { name: "home_hero", selector: ".hero-inner" },
11          { name: "home_recommendations", selector: ".intro-content" },
12          { name: "home_nav", selector: "body > div.category-menu" },
13        ],
14      },
15      {
16        name: "product_detail",
17        isMatch: () => Evergage.cashDom("div.container.product-intro").length > 0,
18        action: "View Product",
19        catalog: {
20          Product: {
21            _id: Evergage.resolvers.fromHref((url) => url.split("/").splice(-1)[0].toUpperCase()),
22            name: Evergage.resolvers.fromSelector("h1"),
23            price: 1,
24            url: Evergage.resolvers.fromHref(),
25            imageUrl: Evergage.resolvers.fromSelectorAttribute(".img-responsive", "src"),
26            inventoryCount: 1,
27            categories: Evergage.resolvers.buildCategoryId(
28              ".nav a.current span",
29              null,
30              null,
31              (id) => {
32                return [id];
33              },
34            ),
35            relatedCatalogObjects: {
36              // In case you're using 'dimensions' instead of 'relatedCatalogObjects', you can continue to do so as they both function the same way.
37              ItemClass: Evergage.resolvers.fromSelectorMultiple("li.current a"),
38            },
39          },
40        },
41        listeners: [
42          Evergage.listener("click", ".product-intro .btn.green-btn.btn-med", (event) => {
43            Evergage.sendEvent({
44              itemAction: Evergage.ItemAction.AddToCart,
45              cart: {
46                singleLine: {
47                  Product: {
48                    _id: Evergage.util
49                      .getPathname(window.location.href)
50                      .split("/")
51                      .splice(-1)[0]
52                      .toUpperCase(),
53                    price: 1,
54                    quantity: 1,
55                  },
56                },
57              },
58            });
59          }),
60        ],
61        contentZones: [{ name: "product_detail_cta", selector: ".btn.green-btn.btn-med" }],
62      },
63      {
64        name: "pre_approved",
65        isMatch: () => /\/get-preapproved/.test(window.location.href),
66        action: "Pre-Approved",
67        listeners: [
68          Evergage.listener("click", "#msform", (event) => {
69            if (Evergage.cashDom(event.target).closest(".next").length > 0) {
70              const step = Evergage.cashDom("#progressbar .active").length - 1;
71              if (step > 0) {
72                const email = Evergage.cashDom("#form-application-email").val();
73                let actionEvent = {
74                  user: {},
75                  action: "Get Pre-Approved Form Step " + step + " Submit",
76                };
77                if (email) {
78                  actionEvent.user.id = email;
79                }
80                Evergage.sendEvent(actionEvent);
81              }
82            } else if (Evergage.cashDom(event.target).closest(".save").length > 0) {
83              const step = Evergage.cashDom("#progressbar .active").length;
84              if (step > 0) {
85                const email = Evergage.cashDom("#form-application-email").val();
86                let actionEvent = {
87                  user: {
88                    attributes: { LifecycleState: "Mortgage Application Open" },
89                  },
90                  action: "Get Pre-Approved Form Step " + step + " Save For Later",
91                };
92                if (email) {
93                  actionEvent.user.id = email;
94                }
95                Evergage.sendEvent(actionEvent);
96              }
97            }
98          }),
99        ],
100      },
101    ],
102  };
103
104  Evergage.initSitemap(config);
105});