We'll cover the steps involved in implementing the Qubit cartridge on your Salesforce Commerce Cloud site.
A cartridge is a mechanism for packaging and deploying program code and data. Our cartridge contains all the necessary elements to integrate your Salesforce eCommerce solution with Qubit, including smartserve.js and our QProtocol data layer, with all the data points you need to better understand your visitors, uncover relevant insights, and discover opportunities for personalization.
From a technical perspective, the setup can be divided into 2 steps:
Before getting started, we will briefly provide some context around the events collected by our data layer, QProtocol, looking in particular at the events typically emitted on the different page types found on an eCommerce platform. We will also look at the types of pages you can track by installing the Qubit cartridge.
In the following table we identify the QProtocol events typically emitted by page type:
Page | Available events |
---|---|
All | ecView, ecUser, ecBasketItem, ecBasketSummary |
Home | ecView, ecUser, ecBasketItem, ecBasketSummary |
Product | ecView, ecUser, ecProduct, ecBasketItem, ecBasketSummary |
Listing | ecView, ecUser, ecBasketItem, ecBasketSummary |
Basket | ecView, ecUser, ecBasketItem, ecBasketSummary |
Checkout | ecView, ecUser, ecBasketItem, ecBasketSummary |
Confirmation | ecView, ecUser, ecBasketItemTransaction, ecBasketTransactionSummary |
The Qubit cartridge includes a set of methods that we can add to the ISML templates for tracking.
In the following table, we identify a list of pages that you can track in Site Genesis with Qubit:
Page type | Description |
---|---|
home | a home page |
content | all other pages, not from the list |
product | a product detail page |
category | a page listing multiple products |
search | a search results page |
basket | a cart view page |
checkout | a page summarizing order details and the last page before an order is submitted |
confirmation | the post-purchase confirmation page |
Open Studio and select File > Import > General > Existing Project into Workspace:
Navigate to the directory containing int_qubit, and select it. Then select Finish. Finally, select OK to link the cartridge to the sandbox
Select your sandbox connection and select Properties. Select Project References and check-in int_qubit
Open Business Manager and select Administration > Sites > Manage Sites and then select the Salesforce Commerce Cloud site you want to install the cartridge on
In the Settings tab add the following to the Cartridges path at the beginning of the line:
int_qubit:
Select Apply to save the change
In Import & Export, select Import and select the file system-objecttype-extensions.xml
Open your site in the Business Manager and select Merchant Tools > Custom Preferences > Qubit
Add or edit the configuration as required. When done, select Save to commit.
Refer to the following table for details of the options available to configure the cartridge:
Name | Type | Description | Default |
---|---|---|---|
Qubit Enabled* | Boolean | Whether the Qubit integration is enabled | Yes |
Tracking ID* | String | The tracking Id for your site, as provided by Qubit | n/a |
Emit Events* | Boolean | Whether Qubit events are emitted | Yes |
UV API Script | String | The UV API script | n/a |
Enable ecEvents for your store | Array of Strings | Defines which events will be emitted on your site, and therefore what data will be passed to Qubit |
|
Package* | Enumeration | Defines which Qubit package has been selected by the client | Pro |
Smartserve URL* | String | The URL of the smartserve.js provided by Qubit, e.g. | n/a |
Smartserve Location* | Enumeration | The page location where the smartserve script will be injected | Start of HEAD |
Smartserve Asynchronous* | Boolean | Whether the smartserve file should be loaded asynchronously | Yes |
Namespace | String | The custom namespace value, provided by Qubit during onboarding and only required for those client emitting custom events or fields | n/a |
Send Product Listing Events* | Boolean | Whether to enable the sending of product events from listing pages | No |
Product Listing Event Limit | Number | Limit the number of product events sent on a product listing page | 20 |
Product Stock Data | Boolean | Whether to include the product stock level in product events | Yes |
Always Send Basket Events* | Boolean | Whether to send basket events on every page or only in the checkout funnel | Yes |
Checkout Pages | String | Comma separated controller names in the checkout funnel, e.g. | n/a |
Product’s custom SKU attribute | String | Name of the product's custom attribute containing the SKU | n/a |
INFO: * denotes a mandatory configuration.
The following changes must be done in the storefront cartridge.
In app_storefront_core/cartridge/js/app.js edit the Qubit module path to match the cartridge location:
Add the following line to app_storefront_core/cartridge/js/app.js:
qubit.init();
You will need to modify Resources.ds to get the controller URL and preferences.
Add the following lines to app_storefront_core/cartridge/scripts/util/Resource.ds:
//Qubit Integration
ecBasketItemAction: URLUtils.url('Qubit-BasketItemAction').toString()
//Qubit Integration
Add the following lines to ResouceHelper.getPreferences
in app_storefront_core/cartridge/scripts/util/Resource.ds:
//Qubit Integration
QUBIT_NAMESPACE: Site.getCurrent().getCustomPreferenceValue('qubitNamespace'),
SEND_PRODUCT_LISTING_EVENTS:Site.getCurrent().getCustomPreferenceValue('sendProductListingEvents'),
PRODUCT_LISTING_EVENTS_LIMIT:Site.getCurrent().getCustomPreferenceValue('productListingEventLimit'),
ALWAYS_SEND_BASKET_EVENTS:Site.getCurrent().getCustomPreferenceValue('alwaysSendBasketEvents'),
QUBIT_PACKAGE: Site.getCurrent().getCustomPreferenceValue('qubitPackage').getValue(),
EMIT_EVENTS: Site.getCurrent().getCustomPreferenceValue('emitEvents'),
QUBIT_ENABLE: Site.getCurrent().getCustomPreferenceValue('qubitEnable')
//Qubit Integration
Add the following lines to util/modules.isml:
<iscomment>
Render Qubit scripts information
</iscomment>
<ismodule template="qubit/qubittrackscript"
name="qubittrackscript"
/>
<iscomment>
Render Qubit events information
</iscomment>
<ismodule template="qubit/qubittrackeventdata"
name="qubittrackeventdata"
attribute="event_type"
attribute="page_name"
attribute="page_data"
attribute="is_call_event"
/>
To ensure the best possible data accuracy and experience delivery, it is important to call the module as early as possible on the page.
You can call the Qubit module from a number of different page locations.
htmlhead.isml
Add the following lines, to components/header/htmlhead.isml in the desired position
Top header:
<isinclude template="qubit/uvapiscript" />
<isinclude template="qubit/smartservestartofhead" />
Bottom header:
<isinclude template="qubit/smartserveendofhead" />
footer_UI.isml
Add the following lines to components/header/footer_UI.isml in the desired position
<isinclude template="qubit/smartserveendofbody" />
To add the module for events, add the following lines to util/modules.isml:
<iscomment>
Render Qubit scripts information
</iscomment>
<ismodule template="qubit/qubittrackscript"
name="qubittrackscript"
/>
<iscomment>
Render Qubit events information
</iscomment>
<ismodule template="qubit/qubittrackeventdata"
name="qubittrackeventdata"
attribute="event_type"
attribute="page_name"
attribute="page_data"
attribute="is_call_event"
/>
Emitted on every page before any other event and with the type field populated.
Add the following lines after the </isscript>
tag in components/footer/footer.isml:
<iscomment> Qubit Integration </iscomment>
<isqubittrackeventdata event_type="ecView"/>
<iscomment> Qubit Integration </iscomment>
Emitted once per view to report visitor metadata. The event should be emitted on every page as long as there is data available for the user.
Add the following lines in the components/header/headercustomerinfo.isml template file:
<iscomment> Qubit Integration </iscomment>
<isinclude template="util/modules"/>
<isqubittrackeventdata event_type="ecUser"/>
<iscomment> Qubit Integration </iscomment>
Emitted on product detail pages.
Add the following lines at the bottom of product/producttile.isml:
<iscomment> Qubit Integration </iscomment>
<isinclude template="util/modules"/>
<isqubittrackeventdata event_type="ecProduct" page_name="search" page_data="${Product}" />
<iscomment> Qubit Integration </iscomment>
Add the following lines at the bottom of product/components/variations.isml:
<iscomment> Qubit Integration </iscomment>
<isinclude template="util/modules" />
<isqubittrackeventdata event_type="ecProduct" page_name="${!empty(pdict.isSet) && pdict.isSet ? 'linkedproduct' : 'product'}" page_data="${pdict.Product}" />
<iscomment> Qubit Integration </iscomment>
Add the following lines to product/producttopcontentPS.isml:
<iscomment> Qubit Integration </iscomment>
<isinclude template="util/modules" />
<isqubittrackeventdata event_type="ecProduct" page_name="linkedproduct" page_data="${pdict.Product}" />
<iscomment> Qubit Integration </iscomment>
It is also necessary to make changes to the storefront Javascript files to emit events when the quickview popup opens.
Add the following lines to the load
function in app_storefront_core/cartridge/js/ajax.js:
"var loadAjax = " (assign ajax call in variable call loadAjax)
"return loadAjax;" (return loadAjax at the end of ajax call)
Add the following lines to the replace
section in app_storefront_core/cartridge/js/dialog.js:
"var replaceDialog = " (assign ajax load call in replaceDialog variable)
"return replaceDialog;" (return replaceDialog at the end of the ajax load call)
Add the following lines in the navigateQuickview
function in app_storefront_core/cartridge/js/quickview.js:
"var navigateQV = " (assign dialog.replace call in navigateQV variable)
Add the following lines after the dialog.replace
in the same file:
if (navigateQV) {
navigateQV.then(function() {
$( "body" ).trigger( "productQuickView");
});
}
Emitted on every page, as long as there are one or more items in the user's basket.
Add the following lines before the pliList
loop in checkout/components/minilineitems.isml:
<iscomment> Qubit Integration </iscomment>
<isinclude template="util/modules" />
<isqubittrackeventdata is_call_event="${pdict.p_showreverse}" event_type="ecBasketItem" page_data="${productLineItem}" />
<iscomment> Qubit Integration </iscomment>
Emitted for every interaction with the basket, using the action field to specify whether a line item was added or removed. The event should also contain the summary for the full basket.
For line item additions, add the following lines to app_storefront_core/cartridge/js/pages/product/addToCart.js:
$( "body" ).trigger( "ecBasketItemAction", [$form, 'add']);
For line item removals, replace the code sample inside the deleteProduct
click event in app_storefront_core/cartridge/js/pages/cart.js:
if (removeItemEvent) {e.preventDefault();
}
else {
removeItemEvent = true;
}
With:
var data = {
'pid': $(this).closest('.cart-row').find('.sku .value').text(),
'Quantity': $(this).closest('.cart-row').find('.item-quantity input[name$="quantity"]').val(),
'action': 'remove'
};
$( "body" ).trigger( "ecBasketItemAction", [data, 'remove'], function () {
if (removeItemEvent) {
e.preventDefault();
} else {
removeItemEvent = true;
}
});
Emitted only on order summary pages with transaction.id
.
Add the following lines after the Order
variable at top of components/order/orderdetails.isml:
<iscomment> Qubit Integration </iscomment>
<isinclude template="util/modules" />
<isqubittrackeventdata page_name="transactionId" page_data="${Order.orderNo}" />
<iscomment> Qubit Integration </iscomment>
Add the following lines inside the productLineItem
loop in components/order/orderdetails.isml:
<iscomment> Qubit Integration </iscomment>
<isqubittrackeventdata event_type="ecBasketItemTransaction" page_data="${productLineItem}" />
<iscomment> Qubit Integration </iscomment>
Emitted on all pages when the visitor has one or more basket items.
Add the following lines inside the mini-cart-content
class div in checkout/cart/minicart.isml:
<iscomment> Qubit Integration </iscomment>
<isqubittrackeventdata event_type="ecBasketSummary" page_data="${pdict.Basket}" />
<iscomment> Qubit Integration </iscomment>
Emitted on the order summary page after ecBasketItemTransaction
events.
Add the following lines before the order-totals-table
class div in components/order/ordertotals.isml:
<iscomment> Qubit Integration </iscomment>
<isinclude template="util/modules" />
<isqubittrackeventdata event_type="ecBasketTransactionSummary" page_data="${LineItemCtnr}" />
<iscomment> Qubit Integration </iscomment>