Skip to content

DataLayer collector

View MD

The DataLayer collector gathers ecommerce data by listening to standard GA4 events on the dataLayer object. If you already send GA4 ecommerce events to Google Analytics, the collector can reuse them with no extra work. If not, this guide walks you through the events to add and shows the required fields for each one.

You can send events in two equivalent ways:

MethodExample
gtaggtag("event", "view_item_list", { ... })
dataLayer.pushwindow.dataLayer.push({ event: "view_item_list", ... })

Add the LBX script inside the <head> element of every page so it can listen for events as the page loads:

<script async src="https://scripts.luigisbox.tech/LBX-XXXXXX.js"></script>

Use this table as a quick glossary of the fields used across the ecommerce events on this page. Not every parameter applies to every event — each event section specifies exactly which fields are required.

ParameterDescription
eventName of the event. Supported values: view_item_list, view_item, select_item, add_to_cart, purchase
item_list_nameIdentifier of the list being reported. Supported values: Autocomplete, Search Results, Product Listing, Recommendation
search_termQuery entered by the user. Required for Search Results and Autocomplete events.
itemsArray of item objects representing the results or products involved in the event.
item_idIdentity of the item. Must match the identity used in your catalog.
item_nameThe display name/title of the item.
indexPosition of the item in the list. Note: When using pagination, offset by the number of items on previous pages.
typeContent type of the item. Supported values: item (default), category, brand, article
pricePrice of the item. For purchase events, this is the price of a single unit.
quantityNumber of units. Used only in purchase events.
filtersObject of filter names and their values. When a filter has multiple values, pass them as an array. You can also use these reserved keys: _Guid (unique identifier of the API response), _Variant (A/B test variant identifier for the list).
transaction_idUnique identifier of the transaction.
valueTotal monetary value of the event.
currency3-letter ISO 4217 currency code (e.g., EUR, USD).

Start here if you want the shortest path to a working integration. The table below shows which events to implement for each feature — click an event name to jump to its example.

EventGA4 nameWhen to fire
Autocompleteview_item_listUser sees autocomplete suggestions
Search resultsview_item_listSearch results page loads
Product listingview_item_listCategory / Brand listing page loads
Recommendationsview_item_listRecommendation widget renders
No resultsview_item_listSearch returns zero results
Clickselect_itemUser clicks a result
Add to cartadd_to_cartUser adds an item to cart
TransactionpurchaseUser completes a purchase
Impressionview_itemUser visits a product detail page

The examples below show the minimum required parameters. If you already collect additional GA4 fields, you can include them as well.

Each event section includes: required fields, plus a tabbed example for dataLayer.push and gtag.

Send a view_item_list event when autocomplete suggestions are displayed.

FieldRequiredDescription
item_list_nameYesSet to "Autocomplete".
search_termYesQuery entered by the user.
items[]YesArray of result objects. Each item includes: item_id (item identity), item_name (display name/title), index (position in the list), price (item price, optional), type (content type, e.g. item, category, brand — defaults to item)
filtersActive filters applied to the results. You can also send: _Guid (guid from the Autocomplete API response), _Variant (A/B test variant identifier)
window.dataLayer.push({
event: "view_item_list",
ecommerce: {
item_list_name: "Autocomplete",
search_term: "phone",
items: [
{
item_id: "CAT_12345",
item_name: "Phones",
index: 1,
type: "category", // Define a result type. If left empty, fallbacks to "item".
},
{
item_id: "SKU_12345",
item_name: "Stan and Friends Tee",
index: 2, // If pagination is used, offset the index by the number of items before the current page.
price: 9.99,
},
{
item_id: "SKU_12346",
item_name: "Google Grey Women's Tee",
index: 3,
price: 20.99,
type: "item",
}
],
filters: {
"_Guid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", // Autocomplete API response guid
"_Variant": "Original", // A/B test variant (optional)
"Color": ["Black", "Silver"],
"Operating system": "Android"
}
},
});

Send a view_item_list event when the search results list is displayed. The structure is identical to Autocomplete, except item_list_name is "Search Results".

FieldRequiredDescription
item_list_nameYesSet to "Search Results".
search_termYesQuery entered by the user.
items[]YesArray of result objects. Each item includes: item_id (item identity), item_name (display name/title), index (position in the list), price (item price, optional), type (content type, e.g. item, category — defaults to item)
filtersActive filters applied to the results. You can also send: _Guid (guid from the Search API response), _Variant (A/B test variant identifier)
window.dataLayer.push({
event: "view_item_list",
ecommerce: {
item_list_name: "Search Results",
search_term: "Phone",
items: [
{
item_id: "CAT_12345",
item_name: "Phones",
index: 1,
type: "category", // Define a result type. If left empty, fallbacks to "item".
},
{
item_id: "SKU_12345",
item_name: "Stan and Friends Tee",
index: 2, // If pagination is used, offset the index by the number of items before the current page.
price: 9.99,
type: "item",
},
{
item_id: "SKU_12346",
item_name: "Google Grey Women's Tee",
index: 3,
price: 20.99,
type: "item",
}
],
filters: {
"_Guid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", // Search API response guid
"_Variant": "Original", // A/B test variant (optional)
"Color": ["Black", "Silver"],
"Operating system": "Android"
}
}
});

Send a view_item_list event when a category or listing page displays a product list.

FieldRequiredDescription
item_list_nameYesSet to "Product Listing".
items[]YesArray of product objects. Each item includes: item_id (item identity), item_name (display name/title), index (position in the list), price (item price), type (content type, typically item)
scopesYesObject identifying the current category: CategoryLabel (human-readable category path, levels separated by pipe, e.g. Electronics | Phones | Black Phones), CategoryIdentity (category identifier matching the identity in your catalog).
filtersAdditional filters selected by the user. You can also send: _Guid (guid from the Search API response), _Variant (A/B test variant identifier)
window.dataLayer.push({
event: "view_item_list",
ecommerce: {
item_list_name: "Product Listing",
items: [
{
item_id: "SKU_12345",
item_name: "Black phone 256gb",
index: 1, // If pagination is used, offset the index by the number of items before the current page.
price: 9.99,
type: "item",
},
{
item_id: "SKU_12346",
item_name: "Black phone 128gb",
index: 2,
price: 20.99,
type: "item",
}
],
scopes: {
"CategoryLabel": "Electronics | Phones | Black Phones",
"CategoryIdentity": "12345",
},
filters: {
"_Guid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", // Search API response guid
"_Variant": "Original", // A/B test variant (optional)
"Operating system": "Android" // Pass additional filters selected by the user
}
}
});

Send a view_item_list event when a recommendation widget displays items.

FieldRequiredDescription
item_list_nameYesSet to "Recommendation".
items[]YesArray of recommended item objects. Each item includes: item_id (item identity), item_name (display name/title), index (position in the list), price (item price), type (content type, typically item)
filtersYesRecommendation metadata passed as filter keys: RecommenderClientId (unique identifier of the recommender), RecommendationId (unique identifier of the recommendation set), ItemIds (input items from the recommendation request), Recommender (name of the recommender), Type (type of the recommender), _Variant (A/B test variant identifier).
window.dataLayer.push({
event: "view_item_list",
ecommerce: {
item_list_name: "Recommendation",
items: [
{
item_id: "SKU_12345",
item_name: "Stan and Friends Tee",
index: 1,
price: 9.99,
type: "item",
},
{
item_id: "SKU_12346",
item_name: "Google Grey Women's Tee",
index: 2,
price: 20.99,
type: "item",
}
],
filters: {
"RecommenderClientId": "Basket",
"ItemIds": ["/products/123", "/products/129"],
"Type": "basket",
"RecommendationId": "1abc2de3-f456-7890-1g23-hijk45l6789m",
"_Variant": "Luigis",
}
}
});

Send the event even when a search returns no results so Luigi’s Box can track zero-result queries. Set items to an empty array.

FieldRequiredDescription
item_list_nameYesSet to "Search Results" or "Autocomplete" depending on the context.
search_termYesQuery that returned no results.
itemsYesSet to an empty array: [].
filtersActive filters applied at the time of the search.
window.dataLayer.push({
event: "view_item_list",
ecommerce: {
item_list_name: "Search Results",
search_term: "Phone",
items: [],
filters: {
"Color": ["Burgundy"],
"Operating system": "Android"
}
}
});

Send a select_item event when a user clicks a result from any list (search, autocomplete, recommendations, or product listing).

FieldRequiredDescription
items[]YesArray containing a single item object: item_id (identity of the clicked item)
window.dataLayer.push({
event: "select_item",
ecommerce: {
items: [
{
item_id: "SKU_12345",
}
]
}
});

Send an add_to_cart event when a user adds an item to their cart.

FieldRequiredDescription
currencyYes3-letter ISO 4217 currency code (e.g., EUR).
valueYesMonetary value of the item being added.
items[]YesArray containing a single item object: item_id (identity of the item being added)
window.dataLayer.push({
event: "add_to_cart",
ecommerce: {
currency: "EUR",
value: 7.77,
items: [
{
item_id: "SKU_12345",
}
]
}
});

Send a purchase event after the purchase is confirmed.

FieldRequiredDescription
transaction_idYesUnique identifier of the transaction.
valueYesTotal monetary value. Sum of (price x quantity) for all items.
currencyYes3-letter ISO 4217 currency code (e.g., EUR).
items[]YesArray of purchased item objects. Each item includes: item_id (item identity), item_name (display name/title), index (position in the list), price (price of a single unit, not the line total), quantity (number of units purchased)
window.dataLayer.push({
event: "purchase",
ecommerce: {
transaction_id: "T_12345",
// Sum of (price * quantity) for all items
value: 72.05,
currency: "EUR",
items: [
{
item_id: "SKU_12345",
item_name: "Stan and Friends Tee",
index: 0,
// Price of a single unit of an item (not the total price)
price: 10.01,
quantity: 3
},
{
item_id: "SKU_12346",
item_name: "Grey Women's Tee",
index: 1,
// Price of a single unit of an item (not the total price)
price: 21.01,
quantity: 2
}
]
}
});

Send a view_item event when a user visits a product detail page.

FieldRequiredDescription
items[]YesArray containing a single item object: item_id (identity of the viewed product)
window.dataLayer.push({
event: "view_item",
ecommerce: {
items: [
{
item_id: "SKU_12345",
}
]
}
});

By default, Luigi’s Box identifies visitors using a unique ID stored in the _lb cookie.

If you have a stable customer identifier (for example, a logged-in user ID), you can send it to:

  • Recognize the same user across devices and sessions.
  • Enable personalization in backend-only integrations (for example, Search as a Service or server-side recommendations), even before the _lb cookie is available.

Send your identifier by pushing a luigisbox.collector.customer_id event:

dataLayer.push

window.dataLayer.push({
event: 'luigisbox.collector.customer_id',
customer_id: "12345", // Replace with the actual ID
});

If this event is not sent, Luigi’s Box falls back to the automatic _lb cookie identifier.

While integrating, enable the built-in data linter to validate your events in the browser console:

  1. Make sure the Luigi’s Box script is included on the page.
  2. Open your browser’s developer console (press F12).
  3. In the Console tab, run: Luigis.lint = true
  4. Reload the page (keep the console open).

Each time the collector processes an event, it prints a report in the console:

  • Blue logo — data looks correct, no issues found.
  • Red logo — problems detected; review the listed errors.

If you don’t see any linter output, you may be running an older version of the integration script. Contact us and we’ll upgrade it for you.

To disable the linter, run: Luigis.lint = false

Left side: no errors found. Right side: linter found some errors.