Skill level required: Advanced
To set up custom event tracking, you must understand JavaScript, HTML, and the workings of the CMS or eCommerce platform powering your website. If you don’t have the required skills or knowledge, please contact your Customer Success Manager or email us at [email protected].
Introduction
Here we will guide you through the process of adding tracking code to your site for RevLifter to track key events.
The events we require are:
- Product view (which products are being viewed and which promotions are applicable)
- Basket (which items, how many, and which promotions applied to a basket)
- Sale (which items, how many, and which promotions applied to a sale)
The RevLifter tag tracks events by looking for globally scoped (window) variables – this means any JS code will have access to this variable. When these variables are present, our tag will collect and send the data to our data collector.
Implementation
Each event should be written to the global scope (window) of the page with the names detailed below. If this naming convention isn’t possible, please get in touch with your Customer Success Manager or email us at [email protected] – we can reconfigure the tag to look elsewhere.
Unless flagged as optional, all variables are required.
The product id field should be unique to the product and be identical between the product view, basket, and sale events.
We do not currently handle variants of products just the overarching product so this is what needs to be sent in the events.
Other product metadata, such as brand and imageURL, don’t have to be sent on all events but ideally will be sent on at least one – often the product view event.
If you can supply this data in a different structure, please contact your Customer Success Manager or email us at [email protected] – and we can discuss how to integrate it best.
Initialisation
On each page, you need to initialise our queue array. We use this array to capture events that our JavaScript tag will monitor and send to our data collector.
<script>
window._rl_q = window._rl_q || [];
</script>Product view
This captures information about a product when a user lands on a product page, including stock levels and whether any promotions are currently applied.
All fields should be included if they are available in the source data. Please let us know if there are any fields you can’t include, as this may limit the range of campaigns we are able to run.
<script>
_rl_q.push({
// String - Do not alter unless requested
"schema": "1.1",
// String - Do not alter unless requested
"type": "prod",
// String - Product id (not a variant id) must match other events
"id": "abc",
// String - Usually the SKU for the first variant
"sku": "abc123",
// String - Plain text name for your product
"name": "Product Abc",
// Float - Sale price of your item
"price": 1.00,
// String - ISO 4217 Currency code
"currency": "GBP",
// String - Brand for the item
"brand": "Brand A",
// String Array - Categories for the item
"categories": ["Category A", "Sub Category B"],
// String - Plain text details for the item
"detail": "More details about the product",
// String - URL to the main image
"imageURL": "http://example.com/product-abc.jpg",
"stock": {
// Boolean - In-stock status
"inStock": true,
// String(Optional) - "Many" or "Low"
"stockLevel": "Many",
// Integer(Optional) - Stock amount
"stockAmount": 100
},
"promotion": {
// Boolean - Item promotion status
"isOnPromotion": false,
// Float - Price after promotion
"promotionPrice": 1.00,
// Float - Price without promotion
"originalPrice": 2.50,
// String - Name for the promotion
"promotionName": "Promotion A"
}
});
</script>Basket/Cart
This captures all the information from a product view and adds quantity, delivery information, and any details on vouchers or discount codes applied in the basket if this information is available.
A basket/cart event should be added to the queue on every page load, to ensure we have the latest values. We would also advise adding a basket event to the queue on the actual basket/cart page.
All fields should be included if they are available in the source data. Please let us know if there are any fields you can’t include, as this may limit the range of campaigns we are able to run.
<script>
_rl_q.push({
// String - Do not alter unless requested
"schema": "1.1",
// String - Do not alter unless requested
"type": "basket",
"items": [{
// String - Product id (not a variant id) must match other events
"id": "abc",
// String - Usually the SKU for the first variant
"sku": "abc123",
// String - Plain text name for your product
"name": "Product Abc",
// Float - Sale price of your item without any voucher discount applied
"price": 1.00,
// Integer - Amount in basket
"quantity": 5,
// String - Brand for the item
"brand": "Brand A",
// String Array - Categories for the item
"categories": ["Category A", "Sub Category B"],
// String - Plain text details for the item
"detail": "More details about the product",
// String - URL to the main image
"imageURL": "http://example.com/product-abc.jpg",
"stock": {
// Boolean - In-stock status
"inStock": true,
// String(Optional) - "Many" or "Low"
"stockLevel": "Many",
// Integer(Optional) - Stock amount
"stockAmount": 100
},
"promotion": {
// Boolean - Item promotion status
"isOnPromotion": false,
// Float - Price after promotion
"promotionPrice": 1.00,
// Float - Price without promotion
"originalPrice": 2.50,
// String - Name for the promotion
"promotionName": "Promotion A"
}
}, {
"id": "def",
"name": "Product Def",
"price": 0.50,
"quantity": 10,
"brand": "Brand F",
"categories": ["Category F", "Sub Category G"],
"imageURL": "http://example.com/product-def.jpg"
}],
// String - ISO 4217 Currency code
"currency": "GBP",
// Float(Optional) - Shipping
"shipping": 4.00,
// Float(Optional) - Base price is the net total of the line items without any voucher discount applied and without shipping (if not set calculated from the items)
"basePrice": 10.00,
// Float - If a voucher has been used the total discount
"voucherDiscount": 2.00,
// Float(Optional) - basePrice + shipping - voucherDiscount (if not set this is calculated)
"cartTotal": 12.00,
// String - Vouncher code used
"voucherCode": "ABC123",
// Float(Optional) - cartTotal + Tax which should be the price they paid
"priceWithTax": 14.40,
// String - identify what has been shipping has been used
"shippingMethod": "1st"
});
</script>Sending empty baskets
Please note it is important that you send an empty basket when a user has finished purchasing an item or has emptied their basket for any other reason. This is so we know they no longer have any items in their basket:
<script>
_rl_q.push({
schema: "1.1",
type: "basket",
items: []
});
</script>
Basket/Cart Modification (Optional)
❗NOTE: This is an optional event where a full Basket/Cart event can’t be added to the queue.
❗NOTE: You will need to contact your Customer Success Manager in order to use these events as they are not mapped as standard.
Every basket/cart modification (add/remove/quantity change) should be added to the queue. If possible, we would also advise adding a basket event to the queue on the actual basket/cart page.
Added and Removed are both optional, but at least one must be present.
The items added and removed are tracked via the id field, so it is important that it is unique for each product and matches the id used in the basket event if you are sending one.
All fields should be included if they are available in the source data. Please let us know if there are any fields you can’t include, as this may limit the range of campaigns we are able to run.
<script>
_rl_q.push({
// String - Do not alter unless requested
"schema": "1.1",
// String - Do not alter unless requested
"type": "basketmodification",
// Object(Optional but at least one of added/removed must be present)
"added": [{
// String - Product id (not a variant id) must match other events
"id": "abc",
// Integer - Amount added to the basket (not the total after adding)
"quantity": 5,
// String - Usually the SKU for the first variant
"sku": "abc123",
// String (Optional) - ID used for matching - Must uniquely identify and match an existing basket line item or be a new line item
"equalityValue": "abc123-red-small",
// String - Plain text name for your product
"name": "Product Abc",
// Float - Sale price of your item without any voucher discount applied
"price": 1.00,
// String - ISO 4217 Currency code
"currency": "GBP",
// String - Brand for the item
"brand": "Brand A",
// String Array - Categories for the item
"categories": ["Category A", "Sub Category B"],
// String - Plain text details for the item
"detail": "More details about the product",
// String - URL to the main image
"imageURL": "http://example.com/product-abc.jpg",
"stock": {
// Boolean - In-stock status
"inStock": true,
// String(Optional) - "Many" or "Low"
"stockLevel": "Many",
// Integer(Optional) - Stock amount
"stockAmount": 100
},
"promotion": {
// Boolean - Item promotion status
"isOnPromotion": false,
// Float - Price after promotion
"promotionPrice": 1.0,
// Float - Price without promotion
"originalPrice": 2.5,
// String - Name for the promotion
"promotionName": "Promotion A"
}
}, {
"id": "def",
"quantity": 10,
}],
// Object(Optional but at least one of added/removed must be present)
"removed": [{
"id": "ghi",
// String (Optional) - ID used for matching - Must uniquely identify and match an existing basket line item or be a new line item
"equalityValue": "abc123-red-small",
"quantity": 1,
}, {
"id": "jkl",
// String (Optional) - ID used for matching - Must uniquely identify and match an existing basket line item or be a new line item
"equalityValue": "abc123-red-small",
"quantity": 10,
}]
});
</script>Sending “absolute” basket quantities (Optional)
When sending basket modifications, we keep a log of the items added so if you update the quantity of an item, we expect the number added, not the new total number of items.
For some implementations it is easier to just send the new total quantities. You can do this by setting the AbsoluteQuantities flag on the basket modification event.
<script>
_rl_q.push({
// String - Do not alter unless requested
"schema": "1.1",
// String - Do not alter unless requested
"type": "basketmodification",
// Object(Optional but at least one of added/removed must be present)
"added": [{
// Same as above
// Integer - Total after adding
"quantity": 5,
// Same as above
}],
// Object(Optional but at least one of added/removed must be present)
"removed": [{
// Same as above
// Integer - Total after adding
"quantity": 5
// Same as above
}],
// Boolean: Use these quantities as the total quantities
absoluteQuantities: true
});
</script>
Sale
This is identical to a basket event with an additional orderID property. This is usually emitted on the sale confirmation page.
All fields should be included if they are available in the source data. Please let us know if there are any fields you can’t include, as this may limit the range of campaigns we are able to run.
<script>
_rl_q.push({
// String - Do not alter unless requested
"schema": "1.1",
// String - Do not alter unless requested
"type": "sale",
"items": [{
// String - Product id (not a variant id) must match other events
"id": "abc",
// String - Usually the SKU for the first variant
"sku": "abc123",
// String - Plain text name for your product
"name": "Product Abc",
// Float - Sale price of your item without any voucher discount applied
"price": 1.00,
// Integer - Amount in basket
"quantity": 5,
// String - Brand for the item
"brand": "Brand A",
// String Array - Categories for the item
"categories": ["Category A", "Sub Category B"],
// String - Plain text details for the item
"detail": "More details about the product",
// String - URL to the main image
"imageURL": "http://example.com/product-abc.jpg",
"stock": {
// Boolean - In-stock status
"inStock": true,
// String(Optional) - "Many" or "Low"
"stockLevel": "Many",
// Integer(Optional) - Stock amount
"stockAmount": 100
},
"promotion": {
// Boolean - Item promotion status
"isOnPromotion": false,
// Float - Price after promotion
"promotionPrice": 1.0,
// Float - Price without promotion
"originalPrice": 2.5,
// String - Name for the promotion
"promotionName": "Promotion A"
}
}, {
"id": "def",
"name": "Product Def",
"price": 0.5,
"quantity": 10,
"brand": "Brand F",
"categories": ["Category F", "Sub Category G"],
"imageURL": "http://example.com/product-def.jpg"
}],
// String - ISO 4217 Currency code
"currency": "GBP",
// String - Your order reference
"orderID": "Order#123",
// Float(Optional) - Shipping
"shipping": 4.00,
// Float(Optional) - Base price is the net total of the line items without any voucher discount applied and without shipping (if not set calculated from the items)
"basePrice": 10.00,
// Float - If a voucher has been used the total discount
"voucherDiscount": 2.00,
// Float(Optional) - basePrice + shipping - voucherDiscount (if not set this is calculated)
"cartTotal": 12.00,
// String - Vouncher code used
"voucherCode": "ABC123",
// Float(Optional) - cartTotal + Tax which should be the price they paid
"priceWithTax": 14.40,
// String - identify what has been shipping has been used
"shippingMethod": "1st"
});
</script>Verification
Once you’ve set up the events, you should verify that they operate as expected.
The simplest approach is to open your website in a Chrome browser window and ensure you can see the JavaScript file in the network tag of developer tools.
In Chrome, open the Settings menu by clicking the three dots in the top-right. Go to the More Tools submenu and select Developer Tools. Select the Network tab and refresh your page.
Click XHR to show the calls and search for devt. This will show you all the events the RevLifter tag sent to our data collector.

You can verify the success of your integration by triggering an event based on the conditions you set up (i.e., when you were adding the event to _rl_q).
For example, if you add a basket event into the _rl_q array, you would expect to see a basket request in the list of XHR requests. Click on the request and ensure the payload is correct based on what you added to the _rl_q array.
We’re here to help
If you get stuck or have questions, please get in touch with your Customer Success Manager or email us at [email protected].
When you email us, please provide as much detail about the process you’ve followed and where you’ve got stuck as you can. This will allow us to support you as quickly as possible.