Browse Event
This section outlines how to track key shopper interactions on your site using Pulse events, including category page views, product clicks, cart updates, and order completions. These events help capture critical user behavior signals that power Unbxd’s analytics, search relevance, and recommendation models.
You can skip this event if you have NOT purchased Netcore Unbxd Browse.
The mandatory page and pageType payloads should be triggered on all category pages.
Activating the categoryPage event relies on the configuration of category fields in your feed and the method used to request the category API. To enable this event, make sure the UnbxdAnalyticsConf object is properly set on the window with correct page and page_type values.
In this reference markup, the page and page_type values are extracted by targeting the UnbxdAnalyticsConf object from the window.
window.UnbxdAnalyticsConf = window.UnbxdAnalyticsConf || {};
window.UnbxdAnalyticsConf["page"] =
"{{categoryPath used for category api call (value of 'p' parameter)}}";
window.UnbxdAnalyticsConf["page_type"] = "BOOLEAN";Click Event
The mandatory pid payload is captured from the product element of the Products Listing Page, and the click event is triggered when the shopper clicks on the product.
Key points:
- The
pidcan be obtained from an HTML attribute or a URL, such as theimg_urlorhrefon the product card. - If the unique ID for the product has not been added to the product element, refer to the Netcore Unbxd Search API response to pass it.
<div class="search-results-grid" pageType="search">
<div class="search-result" data-item-id="371823">
<a href="https://www.example.com/product/productname">
<img src="https://www.example.com/images/productname.png" />
<span>Organic Honeycrisp Apple</span>
</a>
</div>
<div class="search-result" data-item-id="371811">
<a href="https://www.example.com/product/productname">
<img src="https://www.example.com/images/productname.png" />
<span>Organic Banana</span>
</a>
</div>
</div>Facet Event
Pulse tracks facet and filter interactions on your website, including filter clicks, clears, applies, pre-selected filters from the URL, and range sliders. These events capture how shoppers refine results on listing pages and play a critical role in improving relevance, analytics, and personalisation.
Pulse listens on mouseup for the elements you list under triggers. When a shopper changes a filter, it reads each facet's group name and value from the DOM (or from callbacks you provide), and then emits the facet event according to your analytics setup.
Important Point to RememberPulse resolves the facet group name and option value from the DOM using
closest()from the click target. Both must resolve inside a single facet group wrapper. If your CSS class names are unstable (for example, generated hashes), add stabledata-*attributes on facet groups or options so selectors remain reliable.
Integrate Facets Tracking
- Review prerequisites: Every facet interaction requires the group name and option value to be resolvable from the DOM, plus a way to read pre-selected filters from the URL. Ensure these values are present in the page, DOM, or URL before sending the event. Refer to the prerequisites section below for detailed information.
- Provide selectors and callbacks: Share the CSS selectors and the
getDataFromCB,onFacetClick, andonPreSelectedAtURLcallbacks for your storefront so group names and option values resolve correctly from your markup. - Validate facet data retrieval: Verify that Pulse can retrieve the facet group name, option value, and pre-selected filters from the DOM and URL.
Mandatory Configuration
Below are the items you must supply so the facets configuration can be written and maintained.
| Deliverable | What to provide |
|---|---|
| Per-group wrapper | A selector that matches one facet group at a time (for example, one "Color" block). Pulse uses closest() from the click target, so name and value must resolve inside that wrapper. |
| Click targets | Selector(s) for each clickable option: checkbox row, link, swatch, slider handle, and so on. |
| Selected state | How a chosen option is indicated in the DOM (for example, input:checked or a selected class). |
| Facet group label | Where the visible group title appears (for example, the heading for "Color" or "Brand"). |
| Option label / value | Where the visible or attributable value appears for each option (text node, label, or stable data-*). |
| Clear / Apply controls | If the UI has clear-all, clear-group, apply-group, or apply-all controls, the selectors for those controls. Omit if not present. |
| Filter URL rules | How selected filters appear in the URL when a user lands on a pre-filtered link (query string layout, which keys are facets vs. navigation). Used to implement onPreSelectedAtURL. |
| Range / slider UI | If price or other ranges use sliders or min/max inputs, describe that UI separately from checkbox-style facets. |
Configuration Shape
The facets configuration is a top-level array on the customer analytics config object. Use a separate array entry when the layout differs (for example, desktop sidebar vs. mobile filter sheet) or when checkbox-style facets and range facets need different selector and callback patterns.
Required Fields
| Field | Purpose |
|---|---|
elemWrapper | Selector for one facet group container. |
triggers | Object of action selectors; must include facetElem. |
triggers.facetElem | The clickable facet option element(s). |
selected | { selector: "..." } — how Pulse detects a selected option. |
name | How to read the facet group name (selector, and/or attr, getDataFromCB). |
value | How to read the facet option value (selector, and/or attr, getDataFromCB). |
facetCB | Callback object; must include onPreSelectedAtURL. |
Optional Triggers
| Key | When to include |
|---|---|
clearAll | Control that clears all filters. |
clearFacets | Control that clears one facet group. |
applyFacets | "Apply" for one group (apply-style UI). |
applyAll | "Apply all" for pending changes. |
If you omit apply-related triggers, tracking follows each facet click. If you include them, Pulse uses accumulate-then-apply behavior for those controls.
Optional Fields
| Key | Purpose |
|---|---|
facetCB.onFacetClick | Custom handling for a click; typically required for range/slider facets. |
misc | Optional extra configuration supported by your analytics build, if applicable. |
Check if facet payload data is retrieved
Click-driven facets (checkbox, link, swatch)
The mandatory facet group name and option value are captured from the DOM when the shopper clicks a filter option. The event is triggered on mouseup on any element matching triggers.facetElem.
Key points:
- Each
elemWrapperinstance must contain a node thenameconfiguration can read as the group label. - Each
elemWrapperinstance must contain nodes matchingtriggers.facetElemfor every selectable value. - The markup inside the wrapper must satisfy the
selectedrule when an option is chosen. - Avoid a single
elemWrapperaround the entire filter column if that causesnameto always resolve to the first group's title only. Prefer the repeating root element of each facet group (accordion section, card, column block, and so on). - For collapsed content where styling such as
visibility: hiddenprevents normal text reads, usegetDataFromCBonnameorvaluewith a fallback (for example,textContenton a known descendant).
Example markup of a facet group on the listing page
<div class="filter-group">
<h4 class="filter-heading">Color</h4>
<ul>
<li class="filter-option">
<label>
<input type="checkbox" />
<span class="option-label">Red (24)</span>
</label>
</li>
<li class="filter-option">
<label>
<input type="checkbox" checked />
<span class="option-label">Blue (12)</span>
</label>
</li>
</ul>
</div>
<div class="filter-group">
<h4 class="filter-heading">Brand</h4>
<ul>
<li class="filter-option">
<label>
<input type="checkbox" checked />
<span class="option-label">Nike (8)</span>
</label>
</li>
<li class="filter-option">
<label>
<input type="checkbox" />
<span class="option-label">Adidas (5)</span>
</label>
</li>
</ul>
</div>
<div class="filters-toolbar">
<button class="clear-all" type="button">Clear all</button>
</div>
Range and slider facets
Implement range facets as a separate entry in the facets array (do not combine with checkbox-style markup in one entry unless one selector pattern truly covers both).
Key points:
- Scope
elemWrapperto range/slider blocks only. - Place
triggers.facetElemon controls that receivemouseupwhen the user finishes a change (handles, track, inputs). - Implement
facetCB.onFacetClickto read min/max (or your site's equivalent) from the DOM and return afacetsobject in the callback shape (see the returned shape below). - Implement
onPreSelectedAtURLto reflect the range from the URL or compare current values to defaults, per your URL and DOM design. - Checkbox-style
selectedrules are usually insufficient for sliders;onFacetClickis the standard approach.
Example markup of a price range slider
<div class="filter-group filter-range" data-facet="price">
<h4 class="filter-heading">Price</h4>
<div class="range-slider">
<span class="range-handle handle-min" data-min="0"></span>
<span class="range-handle handle-max" data-max="500"></span>
</div>
<div class="range-values">
<input type="number" class="range-min-input" value="0" />
<input type="number" class="range-max-input" value="500" />
</div>
</div>
Pre-selected filters from URL
The facetCB.onPreSelectedAtURL callback is mandatory. It reads the current page URL (or equivalent) when filters may already be applied and returns the structure the facets callbacks expect.
Key points:
- Use the same facet keys as in click-driven resolution.
- Exclude URL parameters that are not filters (your site defines which keys to skip — commonly search pagination, sort-only params, and so on).
- Return
undefinedwhen there is nothing to return.
Return shape from onPreSelectedAtURL or onFacetClick
{
facets: {
Color: ["Red", "Blue"],
Brand: ["Nike"],
Price: ["0 TO 500"],
},
}
Same filters across different surfaces
| Scenario | What to do |
|---|---|
| Same DOM and same URL encoding on two surfaces (for example, search vs. category listing) | One facets object may suffice. |
| Different DOM or different URL encoding | Add a second facets object with its own selectors and onPreSelectedAtURL. |
Example configuration
The fragment below is illustrative. Your deployment attaches this as the facets property of the full customer config; surrounding keys are omitted on purpose. Replace selectors, URL parsing, and excluded keys with your storefront's real behaviour.
facets: [
{
elemWrapper: ".filter-group",
triggers: {
facetElem: ".filter-group .filter-option",
clearAll: ".filters-toolbar .clear-all",
},
selected: { selector: ".filter-group input[type='checkbox']:checked" },
name: { selector: ".filter-group .filter-heading" },
value: {
selector: ".filter-group .option-label",
getDataFromCB: function (data) {
return (data || "").replace(/\s*\(.*?\)\s*/g, "").trim();
},
},
facetCB: {
onPreSelectedAtURL: function () {
var params = new URLSearchParams(window.location.search);
var facets = {};
params.forEach(function (value, key) {
if (key !== "q" && key !== "page") {
facets[key] = value.split(",");
}
});
if (Object.keys(facets).length > 0) {
return { facets: facets };
}
},
},
},
],
Validation checklist
| Check | Goal |
|---|---|
| Click a filter value | Group name and option value resolve as intended for that UI. |
| Another configured surface (for example, mobile) | Same behavior for the matching facets array entry. |
| Open a bookmarked URL with filters | onPreSelectedAtURL returns the expected structure for that URL. |
| Deselect one value | Behavior matches your agreed test plan for the analytics version in use. |
| Clear all | The clear-all control behaves as configured. |
| Range / slider | Drag/commit and pre-filtered URL cases are both covered by the range entry. |
Cart Event
Quick view/Product details page
The mandatory pid and variantid (if your catalog contains product variants) payloads are captured from the DOM or from a URL, such as the browser URL, img_url, or href in the product details section. The event is triggered when the respective CTA button is clicked.
Example browser URL: https://www.example.com/product/product_107440/107440_green?sale=clearance
<div class="pdp-page" id="quickLook">
<div
class="product-details"
data-item-id="107440"
data-variant-id="107440_green"
>
<div class="hero-img">
<img
src="https://www.example.com/images/product_107440/107440_green.png"
/>
</div>
<div id="productInfo">
<h3>Fresh Blackberry Holland 125 gm</h3>
<input type="number" class="qty-inputbox" />
<span class="price">$10.99</span>
<button class="add-to-wishlist" type="button"></button>
<button class="add-to-cart" type="button"></button>
</div>
</div>
</div>Cart dropdown/Cart page
The mandatory pid and variantid (if your catalog contains product variants) payloads are captured from the DOM or from a URL, such as the browser URL, img_url, or href in the product details section. The event is triggered when the quantities are modified.
<div class="cart-list-grid">
<div class="cart-item" data-item-id="107440">
<a href="https://www.example.com/product/product_107440">
<img src="https://www.example.com/images/product_107440.png" />
</a>
<div id="productInfo">
<h3>Fresh Blackberry Holland 125 gm</h3>
<span class="qty">2</span>
<span class="price">$10.99</span>
<div class="qty-wrap">
<span class="quantity-increase"> + </span>
<input type="text" class="quantity-value" />
<span class="quantity-decrease"> - </span>
</div>
</div>
</div>
<div class="cart-item" data-item-id="245102">
<a href="https://www.example.com/product/product_245102">
<img src="https://www.example.com/images/product_245102.png" />
</a>
<div id="productInfo">
<h3>Fresh Orange Navel Box</h3>
<span class="qty">1</span>
<span class="price">$20.99</span>
<div class="qty-wrap">
<span class="quantity-increase"> + </span>
<input type="text" class="quantity-value" />
<span class="quantity-decrease"> - </span>
</div>
</div>
</div>
</div>window.unbxdOrderData = [
{
pid: "107440", // Required - Product ID
variantId: "107440_01", // Required only if your catalog has variants
qty: "1",
price: "29.99",
},
{
pid: "245102", // Required - Product ID
variantId: "245102_red", // Required only if your catalog has variants
qty: "2",
price: "10.99",
},
];Order Event
It should ideally be tracked on the order-success page. The script below demonstrates how to use the Unbxd.trackMultiple analytics API, which allows one or more products to be passed into the payload to trigger the event.
Payload Details
| Attribute Name | Datatype | Value to Pass |
|---|---|---|
pid | string | Unique ID for the product, to be taken from the Search API response. |
variantId | string | Variant ID of the selected product variant. |
qty | string | Quantity being added by the user. |
price | string | Unit price of the product. |
Refer to the following code snippet.
<script type="text/javascript">
var payload = [
{
pid: '{{uniqueId-of-the-product}}',
variantId: '{{variantId-of-selected-variant}}',
qty: '{{quantity-selected}}',
price: '{{unit-price-for-product}}'
},
{
pid: '{{uniqueId-of-the-product}}',
variantId: '{{variantId-of-selected-variant}}',
qty: '{{quantity-selected}}',
price: '{{unit-price-for-product}}'
}]
if(Unbxd && typeof Unbxd.track === 'function') {
Unbxd.trackMultiple('order', payload)
} else {
console.error('Pulse SDK is missing or initialized out of sequence; ensure it is fully loaded before using it.')
}
</script>