March 18, 2019
DOM Element variable in Google Tag Manager
In this blog, I’ve already published articles about various Google Tag Manager variables, e.g. Auto-event variable, URL variable, Undefined variable, etc. But there’s one more that did not get a lot of publicity here, DOM Element variable. That’s because it requires some technical knowledge and I’m not its biggest fan (due to its fragility).
Those who read my articles for a longer period of time know that I always advocate for having data in the Data Layer rather than trying to scrape something off the website. However, not all projects are perfect and not all of them have dedicated development resources. Therefore, we might end up scraping DOM or using CSS selectors in our triggers.
That’s why I think that you should still know what DOM Element variable is and how to use it.
Table of contents
- A quick introduction to DOM
- Configure DOM Element variable in Google Tag Manager
- What if ID is not present? Enter the zone of CSS Selectors
- How to test your CSS Selector
- How is the DOM element variable different from the Auto-event variable?
- Final words
A quick introduction to DOM
In order to understand what DOM Element variable in GTM is, first you need to have at least a very basic understanding of what DOM is in general. Document Object Model (a.k.a. the DOM) is a dynamic tree-like hierarchical representation of the website’s document. It allows manipulating the website’s document, get values of current website elements, add new, edit or remove existing ones.
If you go to any website and open its source (e.g. CTRL+U on Chrome (WIN)), you’ll see the HTML code of the page. This is the code that a developer wrote to make the website what it looks right now.
But it does not look very dynamic, does it? But if you go back to that very same website and open developer tools (Chrome on Windows: press F12, Chrome on Mac: Command + Option + I), you’ll see a more dynamic representation of the website’s code. If not, switch to the Elements tab.
There are nodes that can be expanded or collapsed (by clicking dark triangles), many nodes have children that can have their own children, nodes can have multiple children, etc. It’s a dynamic tree-like representation of website’s documents. You’re inspecting the HTML DOM here.
As I have mentioned before, DOM allows not only to view/inspect website elements but to manipulate them as well. The easiest and most down-to-earth way to edit nodes in the DOM is to do a double click on a certain node and then change its value or delete/edit/add attributes to an element.
But this is not very scalable and useful. Instead, there should be some better way to do that, right? Yes. DOM supports a bunch of methods that enable developers (and you, if you are skilled enough) to add, edit, delete elements.
As for reading values, getElementById(“some_id”) method will return you the first website element that matches a some_id ID. In the screenshot below, you can see the command (1st line) and the returned element (2nd line).
Another example could be querySelector(), that returns the first website element that matches a certain CSS Selector defined by you.
And that’s a good moment to introduce Google Tag Manager’s DOM Element variable. This type of variable can access the value of a website element that matches a condition defined by you. Let’s take a closer look.
Configure DOM Element variable in Google Tag Manager
To create a new DOM Element variable, go to Variables > Scroll down > New > DOM Element. Click it and let’s take a look at what are the possible settings here.
The first thing you need to set is the selection method. You need to somehow tell GTM which particular website element are you interested in. Elements can be selected either by an ID or by CSS Selector. First, let’s try ID.
Let’s imagine that we have a page with a particular product and you want to get the name of that product. One of the ways to do that would be to read the text of a website element that is Product Title. Do the right click on a product title and let’s hope that we’re lucky enough to find an ID in that element. Bingo!
Double click that ID, copy and paste it in Element ID field in your GTM variable. What about the 2nd field (Attribute name)?
If you leave it empty, the DOM Element variable will return website element’s text (in this example, Dark Blur T-Shirt). However, in some cases, it might be more useful to fetch not the text of an element, but its certain attribute. You can find out what attributes does a certain web element have by inspecting it (this time, I inspected a different element).
See all these highlighted parameters (type, name, id, class)? They are called attributes.
So if you want to get the value of a particular attribute, you’d need to specify its name in the field Attribute Name, e.g. type.
In order to see whether your variable has been created properly, save it, enable/refresh the Preview and Debug mode, and check the variable’s value in the Variables tab.
What if ID is not present? Enter the zone of CSS Selectors
If you’re not familiar with CSS Selectors yet, I highly recommend you reading this Simo Ahava’s guide where he shares a bunch of useful selectors for Google Tag Manager.
In a nutshell, CSS Selectors allow targeting specific website elements in order to apply a style to them (after all, CSS is for styling the website). Here’s a basic example of CSS:
This piece of CSS states that all elements containing the class attribute red-button will be colored red (color code #FF0000). Targeting elements in CSS is possible thanks to CSS Selectors. In the example above, the CSS Selector is .red-button and it targets all elements of which class is red-button (a dot in CSS means “class”).
But CSS selectors are so versatile that they can be used in DOM Methods too. If you want to pick a certain website element and read its value, you can write a more complex CSS selector, for example, div.call_to_action > .someClass.
document.querySelector("div.call_to_action > .someClass")
So if you’re curious, go ahead and check Simo’s guide with CSS Selector examples to get some inspiration. If you’re new to selectors and this looks confusing, don’t worry. That’s a pretty normal reaction. But once you start playing around and using it more often, you’ll get onto it.
How to test your CSS Selector
Let’s say that you have finally managed to write a CSS Selector that targets some important element. How can you test it? One way could be to save the variable in GTM interface, refresh the preview mode, then refresh the page and check variable’s value. But that’s a long path.
What if you don’t succeed to create a proper CSS Selector from the first time? What if you end up tweaking the selector 20 times? You’ll have to save the variable, refresh the preview, test 20 times. That’s where the time is wasted.
Replace your_css_selector part with your actual selector. Hit enter and (if your selector is correct) it will return the element that you wanted to target. If you get some unexpected result, tweak the CSS Selector and try again.
When you finally get the desired result, do the final test by entering the CSS Selector in the DOM Element variable’s settings (in GTM UI).
I can’t emphasize enough the risk of using DOM to fetch values of website elements. If you plan to heavily scrape the DOM in your tracking implementation, you need to be aware that a developer can unknowingly change something in the website’s content that can break your DOM Element variables within GTM. The more complex/longer your CSS selectors are, the higher chances of breaking updates will be.
If for some reason, a developer changes a certain class of an element (and you’re using that in your selectors), your DOM Element variables will start returning null, hence your tracking will break.
So before you use CSS Selectors (and DOM Element variable in general), you need to weigh your options and the current situation. If the website is not constantly updated, the chance of breaking changes is lower. But if devs are regularly pushing some improvements, A/B tests are running every day, maybe you should consider getting data via other ways (rather than by scraping the DOM).
What is the other way? Your best option is the Data Layer. Ask a developer to push some important information to the Data Layer and use that in your tag management. From what I’ve seen, chances of breaking Data Layer changes are much lower compared to DOM-related breaking changes.
I completely understand the temptation of using CSS Selectors now. So much power and independence from developers, right? I’d even like to borrow the meme from Jim Gordon:
But in the long run, Data Layer always wins. Actually, you should read the full blog post by Jim about this topic.
How is the DOM element variable different from the Auto-event variable?
If you are familiar with another GTM variable, Auto-event variable, you might be wondering how is DOM Element variable different from AEV?
Auto-event variable allows you to fetch the text (or an attribute) of an element that a visitor/user has interacted with. If a visitor clicks a link, you can access that element’s properties.
DOM Element variable lets you access any element that is present on a page. That way you can get its text or a value of a certain attribute. No interaction is required. In fact, here’s an example of a risky form tracking technique where a successful form submission is counted when a success message element is present on a page. This was done with the help of the DOM Element variable.
DOM Element variable: Final words
DOM Element is a nice tool in your GTM toolkit, however, you should not abuse it. It is a flexible way of fetching particular data on a page, however, if the page content/design is constantly, your DOM Scraping efforts have a high chance of failure.
In fact, very recently in Google Tag Manager community on Facebook, we had a case where one of the members did not understand why suddenly one of his events were not properly tracked in GTM. Turned out something was changed on a website and it broke his CSS Selectors.
So if you’re interested in getting some custom data and making it accessible in GTM, a developer and dataLayer.push should be your best friends.