Enable add-to-cart signals in the Connect web library
You can enable the Connect library to record add-to-cart activity on your website. This activity represents the selection of a product, service or similar offering for purchase or application.
This signal is quite advanced in terms of implementation. There is no one-size-fits-all approach because on one website the Add to Cart button is displayed only on product pages while on another it's on multiple pages.

The "Quick add" button in a product list at Beefcakeswimwear.com
There can be variations of the button like in the examples below.

Two variations of the "Buy" button at Potgang.co.uk

Three variations of the "Buy" button at Amazon.com
Be aware of cases when products are bundled as a special offer.

Product grouping at Amazon.com
Availability
The add-to-cart signal is included into all Connect subscriptions (Pro, Premium and Ultimate).
Configuration
The Connect library provides a method, TLT.logSignal()
with which to send the signal to the Acoustic Connect endpoint, as a JSON object. The Connect library must be initialized before the method is called.
There are multiple ways to trigger the signal, for example as soon as a user clicks on the Add to cart button or later when they open the shopping cart. It all depends on how your website is structured and on the purchasing flows it supports.
Required fields
You must populate the required fields before sending the signal: the name, ID, quantity and price of the product as well as the currency. If just one required value is missing, the signal gets discarded. If a field isn’t applicable to your business, use a hardcoded value as a placeholder.
On some websites, you may need separate pieces of logic to support all available purchasing flows (for example, from the product list page, from the product view page and from the product view modal).
If there is a data layer on your website, it will make your work easier.
Field | Values | Definition |
---|---|---|
category | String. Valid value - Behavior . | The category of the signal. Do not edit. |
currency | String. Valid values - ISO 4217 currency codes. | The currency in which the price of the product is represented |
effect | String. Valid values: - negative - positive | Describes the effect of the signal on engagement. It is intended to be used for engagement index scoring. We suggest sending positive for all add-to-cart signals. |
name | String, up to 256 characters | Assign a name to the signal to differentiate it from other signals. |
productId | String | The identifier of the product. It may coincide with the SKU. |
productName | String | The name of the product |
quantity | Number | Captures the quantity of the product added to the cart. |
signalType | String. Valid value -addToCart . | The type of signal to enable. Do not edit. |
unitPrice | Number | The unit price of the product |
Optional fields
Field | Values | Definition |
---|---|---|
discount | Number | Discount from the original price. If the exact amount is not provided, you could calculate the difference between the original and the current price. |
productCategory | String | The category that the product falls in based on the product catalog |
productDescription | String | The description of the product |
productImageUrl | String | The URL of the product image |
productUrl | String | The URL of the product page |
promotionId | String | For the use case of on-site marketing like hero images and other calls-to-action, those calls-to-action would have a promotion ID that would "stick" to the behaviors after it. |
signalCustomAttributes | Array of objects | Allows for additional custom attributes. For each custom attribute, add an object with two string fields:name and value . |
shoppingCartUrl | String | The URL of the shopping cart that the add-to-carts are contributing to |
virtualCategory | String | The category is based on how the visitor got to the page, for example from "New arrivals" or "Sale". |
Example
/* eslint-disable padded-blocks */
/* eslint-disable one-var */
(function () {
const signal = {
signalType: "addToCart", // Required
name: "addToCart generated by web site",
category: "Behavior",
productId: "", // Required
productName: "", // Required
productDescription: "",
quantity: 1, // Required
unitPrice: 0, // Required
currency: "USD", // Required
discount: 0,
productCategory: "", // Important, useful for segmentation
productUrl: "",
productImageUrl: "",
shoppingCartUrl: "https://" + window.location.host + "/shopping-cart",
virtualCategory: "",
promotionId: "",
actionState: "",
resumedCartItem: "",
effect: "positive", // Required
signalCustomAttributes: [
{
name: "type",
value: ""
}
]
};
// Array of CSS selectors and configurationTypes
const addToCartButtons = [
{ selector: "#add-to-cart", type: "Product details page" },
{ selector: ".quick-add-button-rounded", type: "Quick add button" }
];
// Attach click listeners to all elements matching selectors, send signal on clicks
addToCartButtons.forEach((addToCartButton) => {
const elements = document.querySelectorAll(addToCartButton.selector);
if (!elements.length) return;
elements.forEach((element) => {
element.addEventListener("click", () => {
// If the click was on a product details page button
if (addToCartButton.type === "Product details page") {
const article = document.querySelector(".product--detailPage");
if (article) {
signal.signalCustomAttributes[0].value = "Product details page";
signal.productId = article.getAttribute("data-sku");
signal.productName = article.getAttribute("data-name");
signal.productUrl = article.getAttribute("data-url");
signal.productImageUrl = article.getAttribute("data-image-url");
signal.quantity = Number(article.querySelector(".cartItem--success").innerText) || 0;
const discountedPrice = Number(article.querySelector(".price-sale").innerText) || 0;
const regularPrice = Number(article.querySelector(".price-default").innerText) || 0;
if (discountedPrice) {
signal.unitPrice = discountedPrice;
signal.discount = Math.round((regularPrice - discountedPrice) * 100) / 100;
} else {
signal.unitPrice = regularPrice;
}
// Optional: display signal in console
console.log("addToCart signal: " + JSON.stringify(signal, undefined, 2));
// Send signal to Acoustic
window.TLT.logSignal(signal);
}
}
if (addToCartButton.type === "Quick add button") {
// Each article in a product grid has its own Quick Add button. Find the closest .product-tile
// element ancestor from the clicked button to identify the correct article in the list.
const article = addToCartButton.closest(".product-tile");
if (article) {
signal.signalCustomAttributes[0].value = "Quick add button";
signal.productId = article.querySelector(".thumbnail_code").innerText || "";
signal.productName = article.querySelector(".thumbnail_name").innerText || "";
signal.productUrl = article.querySelector(".thumbnail_link").href || "";
signal.productImageUrl = article.querySelector(".thumbnail_image").src.split("?")[0] || "";
signal.quantity = 1; // Only one item can be added at a time using Quick Add
const discountedPrice = Number(article.querySelector(".price-sale", "innerText")) || 0;
const regularPrice = Number(article.querySelector(".price-default", "innerText")) || 0;
if (discountedPrice) {
signal.unitPrice = discountedPrice;
signal.discount = Math.round((regularPrice - discountedPrice) * 100) / 100;
} else {
signal.unitPrice = regularPrice;
}
// Optional: display signal in console
console.log("addToCart signal: " + JSON.stringify(signal, undefined, 2));
// Send signal to Acoustic
window.TLT.logSignal(signal);
}
}
});
});
});
}());
Updated 15 days ago