universalLogger UIC module for client-side data layers
What does this module do?
The universalLogger is a client-side, JavaScript module that was designed as an add-on data layer logging feature for Discover. A data layer is a commonly used layer of a website which contains all the data that is generated by visitors engaging with your website. Not all websites have a data layer, but having one enables a more reliable and flexible data collection.
The universalLogger assists with [OOTB] Eventing inside of Discover (as well as with custom events). By using a common data set, the data layer values can be easily mapped into reports & dashboards for rapid consumption. This can include data such as: user information, search info, product info, cart data, application errors, etc.
Supported Data Layers
- Adobe
- Tealium
- Custom Data Layers
Benefits
- Simple configuration of Data Layer object
- Options to clean data layer
- Helper to map data layet object to assist with Discover event building
- Use breakouts to convert JSON arrays into Discover
Step Eventsas show in the sample responses
Updating the UIC with the module
- Add the dataLayer module to the latest DiscoverJS (UIC) library
- Add the following to the core:modules: section of the config:
core:modules:
universalLogger: { enabled: true, events: [ { name: "screenview_load", target: window }, { name: "load", target: window} ] }, - The following is an example configuration. Add the following to the modules: section of the config:
modules: section
universalLogger: { dlObject: "PageDataLayer", // Data Layer object to record blocklistKeys: [ "eventModel.items", // event: view_item_list "eventModel.count_view_promotion", // remove all the promotion items "eventModel.creative_name", "eventModel.creative_slot", "eventModel.promotion_id", "eventModel.promotion_name", "ls.snapinsPage", "gtm", "12.gtm" ], // List of keys to skip logging blocklistValues: [ "view_promotion", "gtm.js", "gtm.dom", "gtm.load", "gtm.start", "gtm.scrollDepth", "gtm.historyChange-v2", ], // List of values to skip logging pushListener: true, // Monitor the data layer for push events after initial capture mapping: { // Optional mapping for DCX Events ("source": "destination") Stacks arrays with | for eventing }, // list of keys to breakout into custom events breakout: [ "search", "view_search_results", "view_cart", "add_to_cart", "add_shipping_info", "add_payment_info", "GA4_purchase" ], maxArrayItems: 100, // maximum items to break out of an array maxSize: 20000, // maximum bytes to log maxKeys: 1000, // maximum number of items to log delay: 1000, // milliseconds to delay first Data Layer inspection logUnflattenedKeys: false },
Configuring the module
- Specify the dataLayer object that you are looking to monitor.
- Optionally, add a list of keys (names) that you wish to block. These keys can be specified as a list of strings [ “key1”, “key2” ] or you can use RegEx in order to block larger selections of keys (Insert example here)
- Optionally, add a list of values that you wish to block. These are exact match strings only.
- Enable or disable the pushListener. A flat data Layer that is updated on load does not need a pushListener (example: Tealium). A more modern/dynamic data layer may dispatch updates to the data layer and requires a pushListener to capture these updates (example: GA4).
- Optionally mapping can be configured to normalize key names. This is not normally used.
- Optionally breakout can be configured to break arrays into individual events (step attributes) so they can be consumed much more easily in Discover.
- maxArrayItems, maxSize, maxKeys are all safety checks which will help make sure we do not overload Discover with invalid data (or potentially data injected by a potential attacker).
- The delay can be configured to wait for a small amount of time before trying to capture the data layer. This is usually left at 500 milliseconds unless the data layer in use is slow to load in the browser.
Sample responses
{
"timestamp": 1740001627985,
"type": 19,
"offset": 57274,
"screenViewPath": "/",
"screenviewOffset": 29249,
"count": 76,
"fromWeb": true,
"dataLayer": {
"data": {
"event": "view_cart",
"eventModel.count_view_cart": 1,
"eventModel.currency": "USD",
"eventModel.value": "894.96000",
"eventModel.hcl_account": null,
"eventModel.hclMarketplace": "Ruby"
}
}
},
{
"interfaceType": "fetch",
"originalURL": "discover.hcl-commerce.com/wcs/resources/store/41/person/@self",
"requestURL": "discover.hcl-commerce.com/wcs/resources/store/41/person/@self",
"description": "API Monitor - discover.hcl-commerce.com/wcs/resources/store/41/person/@self",
"method": "GET",
"status": 200,
"statusText": "OK",
"async": true,
"ajaxResponseTime": 307,
"responseType": "basic",
"locationHref": "https://discover.hcl-commerce.com/",
"response": {
"lastName": "Tester",
"country": "United States",
"zipCode": "01803",
"registrationStatus": "RegisteredPerson",
"preferredLanguage": "en_US",
"resourceId": "https://ts-app:5443/wcs/resources/store/41/person/@self?langId=-1",
"city": "Boston",
"preferredCurrency": "USD",
"distinguishedName": "uid=master@tester.com,o=default organization,o=root organization",
"orgizationId": "-2000",
"addressId": "3074457364512099112",
"accountStatus": "Enabled",
"email1": "master@tester.com",
"profileType": "Consumer",
"state": "Massachusetts",
"challengeQuestion": "-",
"nickName": "master@tester.com",
"addressType": "ShippingAndBilling",
"resourceName": "person",
"addressLine": [
"101 Main Street",
"",
""
],
"userId": "3036",
"registrationDateTime": "2025-02-19T21:43:07.082Z",
"organizationDistinguishedName": "o=default organization,o=root organization",
"firstName": "Master",
"logonId": "master@tester.com",
"receiveEmailPreference": [
{
"storeID": "41",
"value": "false"
}
],
"lastUpdate": "2025-02-19T21:43:07.082Z",
"registrationApprovalStatus": "Approved",
"passwordExpired": "false",
"primary": "true",
"receiveSMSPreference": [
{
"storeID": "41",
"value": "false"
}
]
}
}