Quick tip – setting products or listX in DTM

If I had a Franken for each time someone asked me how to set s.products and List Vars using DTM, … but I don’t. And the question is valid. And it comes up a lot, so let me write down how it is done.

Note: my friend Pedro was faster this time, see his post on products and the W3C data layer. But since I had written most of this post, and since more is always better, I decided to post this anyway.

Problem Statement

On my site, I want to track the products that people look at, put into their basket, and buy. How do I populate s.products using DTM?


I have teasers on my homepage, I want to track impressions and click-through rates for them. List Vars seem like the answer, but how do I set them using DTM?

Neither s.products, nor s.list1s.list3 are available in the UI in DTM. There is simply no place where you could assign a value to them!


Thinking back to “pre-Tag Management” days, … no, sorry, that sounds wrong.

When I used to work with Analytics mainly by embedding Javascript into pages (much better!), setting s.products was no different from setting any other “variable“. We would just write some code that determined what to put into it. Some code that would usually contain a loop, of course.

The difference now is that when you use DTM, other “variables” can directly be assigned in the UI, usually using Data Elements.

But the non-visual way of assigning values still exists, albeit slightly hidden.

Have you ever noticed the little “Open Editor” button at the bottom of the “Adobe Analytics” section in your rules?

Open Editor button
If you click that button, an editor window pops up, enabling you to write any Javascript into it. The rule will later execute that code when it runs.

Step by Step

Let me walk you through an example: setting s.products on cart add.

As a pre-requisite, I shall presume that your site is built with a CEDDL-compatible data layer, which means we can see product information in digitalData.product, digitalData.cart, or digitalData.transaction. Nice.

There are two different ways of implementing cart adds: you can take the visitor to the cart when they add something, or you can just make a subtle change to the cart symbol on the page to show that the add was successful.

If you use the first approach, you’ll likely track the cart add on the cart page itself, but if you use the second, you’ll use an Event-based or a Direct Call Rule, because you track the interaction. We’ll use an EBR.

After you have configured the EBR according to your needs (set conditions, select “s.tl” for tracking, adding eVars and events), you can click the “Open Editor” icon at the bottom of the Analytics section to open up a code editor.

Now this editor takes standard Javascript, which DTM will execute when it runs the EBR. The perfect place for us to add logic to fill s.products, isn’t it?

I’m an advocate of tracking product IDs rather than product names, so my code shall loop through the digitalData.cart array and add each product to s.products

if (typeof digitalData.cart !== 'undefined' && digitalData.cart) {
    var sep = "";
    for (var i = 0; i < digitalData.cart.length; i++) {
        s.products += sep + ";" + digitalData.cart[i].productInfo.productID + ";";
        sep = ",";

This is a cart add, so we don’t need quantities or prices.

Easy, isn’t it?

One thing to know (and Pedro mentioned that in his article as well) is that DTM will detect what “variables” you populate in the Javascript part of the rule, and it will automatically adjust s.linkTrackVars and s.linkTrackEvents accordingly. The exception to that rule are “variables” that you inside s.products, those you have to explicitly add yourself.

To DE Or Not To DE?

Since I mentioned Data Elements: should we use them?

Given that we’ll write some custom code into an editor, it is very easy to say “nah, don’t need a DE at all”…

I disagree, out of a non-specific feeling of unease.

Having a Data Element (itself containing custom code for the loop, presumably) means that if DTM ever introduces an option to set s.products or s.listX in the UI, I can easily switch.

The example with the cart add would then look like this:

In the code editor in the Analytics section of the rule, all you’d write would be this:

s.products = _satellite.getVar("product list from cart");

The logic would sit inside the “product list from cart” Data Element, like so:

Data Element with Custom Code
With the custom code simply being:

var result = "";
if (typeof digitalData.cart !== 'undefined' && digitalData.cart) {
    var sep = "";
    for (var i = 0; i < digitalData.cart.length; i++) { 
        result += sep + ";" + digitalData.cart[i].productInfo.productID + ";"; 
        sep = ","; 
return result;

Nicely encapsulated, and, more importantly, ready for the big day when assigning s.products in the DTM UI will be possible.

There. Settled.

8 thoughts on “Quick tip – setting products or listX in DTM

  1. Great post! I’ve been trying to collect/document examples at http://www.digitaldatatactics.com/examples/products.html.
    I do tend to skip the Data Elements for products, for a few reasons: 1, you’re going to have to be in the custom code section of your rules anyways, just to set s.products or listVars. And 2, it often varies a lot by where you are on the site. The cart page needs multiple items taken from digitalData.cart, the product details page needs one item taken from digitalData.products, the transaction page needs multiple items AND cart/revenue taken from digitalData.transaction… in the end, you’d need a different data element for pretty much every rule. But really, the net effect is the same either way- I don’t think there is really a “wrong way”,

    Liked by 1 person

  2. Wasn’t able to replicate this for


    using your technique. After some deliberation (and asking the almighty Google) I did the following:

    var s = _satellite.getToolsByType(‘sc’)[0].getS();
    var _sd_list = _satellite.getVar(“listVar1″);
    s.list1 = _sd_list;

    So thanks for showing the DE-ified method. Maybe my solution in registering the list-variable with the s.linkTrackVars and having an s-object in the code might help some others.

    Do you know, why I was not able to just add the following?
    s.list1 = _satellite.getVar(“listVar1”);

    I have no idea why this did not work.

    Thanks a lot non the less, as this answered a current question of mine and led me to a working solution.


    1. Hm… you’re right.

      There’s code in DTM that explicitly checks for “products” and “events” in rules that fire s.tl(), then adapts trackLinkVars and trackLinkEvents accordingly. But there is no such code for listX.

      Your code is what I’d recommend as a workaround.

      Thanks for sharing, Sven!


  3. I was able to get this working for listVars without setting var s = _satellite.getToolsByType(‘sc’)[0].getS();

    I simply used this:

    s.list1 = _satellite.getVar(“listVar1″);

    which seems to work fine. Is there anything I should watch for?


    1. Hi Trenton,

      Whether you can directly access “s” or not depends on how Analytics has been added in DTM.

      If you use the standard approach of letting DTM manage the Analytics library, DTM will not create an “s” object outside its own scope, which means you will have to retrieve it using the getS() method.

      It seems that in your case, the Analytics library is managed either outside DTM or using the editor window in DTM (an approach Jenn Kunz uses). In that case, you’re fine.



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.