Track More Click Detail with Data Attributes and Google Tag Manager


Tracking when someone clicks on a link is pretty easy in Google Tag Manager. Tracking PDFs is relatively simple, if the link they click on ends in a PDF. It gets a little trickier when we want to know more details about a particular link. If it was a PDF, was it for a Quarterly Report or Client Testimonial?

Custom data attributes are a speedy way to capture additional information about content on the page. It’s a streamlined solution that helps you better understand how a user steers through the site’s content. Custom data attributes are a construct of the HTML 5 spec and are widely supported in all major web browsers. Since it’s valid HTML and HTML is very user-friendly to implement, this makes it all the more attractive to take for a spin.

Let’s avoid additional unnecessary on-page Google Analytics (GA) code obstacles. Let’s veer around clunky, fragile solutions in Google Tag Manager (GTM) and head for easy street!

There are several benefits to implementing and using data attributes:

  1. Your analytics becomes turbocharged with more detail. 
    No other method lets you as easily track extra info about external links, downloads and more. The previously untrackable, can be quickly become trackable with specific details.
  2. Your site tracking becomes less prone to flying off course due to technical errors. 
    Rather than 100 lines of tracking code all over the place, or even on specific links, now your actual code is in one place (Ideally GTM) and it’s less likely to wreck your entire visitor session.
  3. You can easily add additional tracking down the road. 
    By following the rules below you can almost immediately track any clickable things on your website.
  4. Adding data attributes isn’t highly technical.
    A non-technical person with a CMS can begin implementing data attributes manually pretty easily. For best results though, a developer can help surface server level information and repetitively add that info to individual links.

What are Custom Data Attributes?

Custom Data Attributes let you add your own information to HTML elements. Let’s say you have an automobile blog with a number of resources on your site , some involving Cars, and others involving SUVs. If you want to be able to differentiate which is which, it’s not always obvious looking at their linked URLs. For instance, maybe they look like this:

<a href=”/M5Review.pdf”>M5 Review</a>

<a href=”/X3Specs.xls”>X3 Specs</a>

As it stands, there is very little information in those links about the types of documents. To help differentiate them, we can add the following Custom Data Attributes:

<a href=”/M5Review.pdf” data-bodystyle=”car”>M5 Review</a>

<a href=”/X3Specs.xls” data-bodystyle=”suv”>X3 Specs</a>

The format is “data-” followed by a unique word to identify the Custom Data Attribute (bodystyle). Now because of this Custom Data Attribute, “data-bodystyle“, we can better tell which link refers to which type of automobile. You can also have multiple custom attributes and have them refer to other information you want to convey. For instance, in this case, you could have the make of the automobile, or even the date of publication:

<a href=”/M5Review.pdf” data-bodystyle=”car” data-make=”BMW” data-published=”august 2017″>M5 Review</a>

<a href=”/X3Specs.xls” data-bodystyle=”suv”  data-make=”BMW” data-published=”may 2017″>X3 Specs</a>

Custom data attributes are a great way to attach metadata like this to HTML elements without having it be visible to the user (other than by viewing the source code of the page). Because these data attributes happen behind the scenes and they are explicitly for tracking purposes, you know they will are not likely to be meddled with by your content team as they make changes to the site. Bonus!

“Pulling Over” Custom Data Attributes Into Google Tag Manager

Google Tag Manager is a great way that we can interact with these Custom Data Attributes. It’s easy to create a variable that references the custom data of a clicked element. Here’s how we do it:

Create Some Variables from Your Custom Data Attributes.

Each attribute you set up on the page should have its own data layer variable in GTM. The key is in its name. Each Custom Data Attribute has two parts as we mentioned above, the first being “data-” and the second being something unique like “make” or “published“.

Tag Manager takes care of the heavy lifting and makes this information available within the interface.

Here’s what happens behind the scenes – but feel free to skip this paragraph if needed. Google Tag Manager adds the clicked item, that is, everything we know about the clicked link like all the attributes that define it, to the data layer as “gtm.element.” Everything you click a new link or submit a new form, this variable gets updated. Using this, GTM knows the “href” value, the CSS class and other pieces of information about whatever was just clicked. What’s more, any data attributes on the element, it nests these values in the data layer under “dataset.”  This is where you’ll find that second unique part we added.

Putting this all together, you would fetch your attributes by putting something like “gtm.element.dataset.bodytype” into the Data Layer Variable value field. For our other examples, we could use either “gtm.element.dataset.make” or “gtm.element.dataset.published“. Beware of mixed letter casing! There are very specific guidelines regarding data attributes the could adversely affect your tracking. It just might be safer to stay in your lane keep all your data attributes lowercase.

To capture all three, create a variable for each Custom Data Attribute you have included on your link. You can even modify the default value to “(not set)” if there is no value.

From there, you can use these variables in the same way you would use the built-in “click” variables, as they are essentially extensions you built into the click element.

Use Custom Data Attributes to Fire Triggers.

Using the “matches CSS selector” filter within a trigger,  you can use data attributes to help you send off tags. In this case, we could fire an event whenever BMW content was clicked.

Use Custom Data Attributes in Tags.

With the above implemented, we use GTM to send an event into GA. Whenever a user clicks on a link on the page, the trigger captures that link as the “click element”. Then, the variable pulls the data from that element. If you were to click the “M5 Review” PDF link, the variables you set up will contain the values of those data attributes until the next click (or page load, etc.) is processed by Google Tag Manager.

To use these in GA, you’ll you need to set up a GA Event tag to pull these all together. Here’s a GTM tag that sends an event into GA whenever someone clicks on a BMW resource.

As you can see, it also uses the body style attribute we set up as well as the click text of the resource. (I’ve added the examples, that part is not actually part of the tag.)

Tracking these Clicks in Google Analytics.

From this point, it’s easy to create tags to fire events based on the Custom Data Attributes. But we can even leverage these attributes as Custom Dimensions. When someone downloads a resource on our site, we can use Custom Dimensions to Capture the publish date of that resource as well.

Once this is set up, you will be able to track clicks to your site and apply Custom Dimensions as well for additional reporting and analysis. Not only would you see which of those documents were being downloaded, but you would be able to tell the body style that is more popular!

What Else Can We Do?

There are many applications. You can send data attribute-based variables to other sources via GTM. For instance, you could track clicks to a “Get More Information” button and then pass along the Make (a Custom Data Attribute GTM Variable) a user was interested in to a remarketing tag.


Using Custom Data Attributes along with Google Tag Manager is a great way to easily implement a variety of Google Analytics tracking Tags on your website now, as well as giving you a very flexible mechanism for easily adding new tracking in the future.

Dan is a Manager at LunaMetrics with an Agency/Development background. He has over five years of experience working with Google Analytics. He loves leveraging data to help clients make better decisions. Dan loves new methods and lives by the motto, “break it and make it better.” Dan is a husband and father of four future data science-loving sons. When not putting kids to bed, he writes songs and plays guitar.

  • Geo

    A nice post for all who are struggling to make GTM work. I would argue that instead of occupying a custom dimension slot pretty much the same result could have been achieved by simply using the EventAction or EventLabel fields of an event call. If it is a virtual pageview scenario – simply put what you want to analyze in the URL.

    Furthermore, almost every time I’ve been required to use GTM by a client it has been much more painful to do even the most basic of things, compared to a plain and simple setup. It’s mostly an unnecessary layer of complication for me. The little gains from using it are quickly dwarfed by the complexity of the rules and macros you have to setup for even the most basic of things.

    And, in the end, no matter how many containers you wrap the code in it will still rely on JS calls made from outside the containers (dataLayer pushes or others) for any advanced functionality. In this case – the altering of the links with the additional attribute is equivalent to setting up JS calls on them. So in fact that your code is NOT in one place anymore than it is with a trivial setup.

  • Sayf Sharif


    Certainly, how you track something should be adjusted on a case by case basis, and determine what’s the most appropriate, as far as events, virtual pageviews, custom dimensions, or tracking on parameters. The great thing about doing this through Google Tag Manager is how quickly and easily you could change this setup. If I had to manually tag 2,000 different document links, going back to manually change all of them would be tedious, whereas in GTM it would take all of 1 minute.

    I certainly was frustrated with GTM when I first started using it, but the more I work with it, the more I’ve been swung over to being an advocate for it. Even for just 1 analyst/developer on a small site doing nothing complicated, it’s great for it’s debugging abilities, as well as keeping record of older versions, allowing you to roll back your tags if necessary. On complicated and deep sites with long production schedules it’s been amazing.

    And while it’s true that with the dataLayer or a dataLayer.push, or even the Custom Data Attributes, you have “code” on the page, its code that is communicating with GTM, and in GTM you can have all the actual tags that communicate with Google Analytics. No longer will that trackEvent call buried in an included javascript file have to be dug up to explain why the landing page conversions have all dropped to zero.

    I honestly don’t think a single analyst here at LunaMetrics would go back to a non-GTM setup. There are just too many benefits we’ve discovered using it to succinctly list.

    If anyone is really struggling with it (which I understand as I was there at one point), i recommend that they explore it some more, or even take a course like the Google Tag Manager course we are offering coming up in New York or Washington DC.

  • Geo

    Thank you for your response Sayf. I’m glad GTM is helping the LM team in its setups, it shows because this is not the first post in this blog praising GTM. The benefits still allude me, however.

    Now, onto the points you make… In the example from the article – web devs usually have templates for the site so there is no need to go in and change all links individually. It’s really not different at all whether you use GTM or not. Or perhaps you can give me an and the other readers an example where GTM really makes the difference?

    For debugging and for calls buried somewhere on the site – the GA Debugger extentions for Chrome does wonders if you can’t spot the issue in the GA reports themselves. If it is a pure JS issue, you would still need to resort to the Chrome/Firefox/IE JS console, no matter if the code is in a GTM container or not.

  • Sayf Sharif


    If only every client I worked with had templates for every site. You’d be surprised how many companies, even modern tech companies, have a plethora of old static HTML pages, usually knowledge base type sections. Before GTM we would simply include a single JavaScript file on those pages, which would allow us to modify the code later. Add in some jQuery in addition to the tracking code, you name it. Of course that assumes that each page should use the same jQuery, or same GATC. I’ve worked with clients where those thousands of pages were across multiple domains, requiring a variety of setups, and you end up working with a number of different javascript include files for the tracking code with a variety of differences. It’s so much more convenient, and organized, to have just the single container code on all those pages, and worry about the differences inside of GTM.

    A GTM container code placed on 1,000 static pages across 10 domains can easily modify some setting of the GATC based on the URL Host macro, etc. One piece of code across all the sites and pages, and a couple simple macros.

    Not only can having a variety of implementations across a Cross Domain site require a variety of files, but it also presupposes that you have competent reliable developers who implement quickly. I’ve worked with a number like that and it’s wonderful, but it’s not always the case. I’ve also worked in conditions where you may have to wait 2 months for a developer to push a new version of the website live. Using GTM lets the marketing department make changes and additions to their tracking code without being beholden to the developers having the time for them.

    I love the GA Debugger extension, though I hate when it sometimes doesn’t load or work and I have to click and reload the page a few times. 🙂 It’s just not equivalent though. GA Debugger is a great way to find out what’s not working on your site, while GTM Debugging lets you see what’s wrong BEFORE it’s on your site. Particularly in the cases where you have little choice but to push changes to a live site, rather than a development site, the ability to debug something before it goes live can be extremely valuable.

    Who doesn’t have a development test site? Again… you’d be surprised.

    When you have situations with a single super competent developer with full access to all files, can do anything they want, on good and effective test servers, GTM may lose some of it’s necessity. Can a developer code Cross Domain tracking via on page, and JavaScript and jQuery? Sure, but even the best developers make mistakes, and miss links, where GTM won’t. Also why recreate the library? Why use jQuery rather than just code up your own scripts from scratch? There are a number of tags in GTM that already do the heavy lifting for you. Why recreate the script rules in a template to deliver different remarketing tags on various product pages, when you can do it much easier and quicker and cleaner in GTM?

    Another reason is more organization focused. Even if you have a super developer who can do anything and everything instantly, you won’t have him forever. As soon as he or she is gone you’ll hire someone new who might not know that person’s custom code, or where they put the remarketing tag.

    And let’s be honest the super developers are few and far between. More likely a new developer will show up and have to figure everything out from scratch through poorly commented code.

    There are even more benefits than what I’m listing out here. As someone who developed both front and server side code for over a decade before launching into Analytics, as well as being someone who took some time to get used to using Windows and Mac over the command line, I get the feeling of having more control over things when you are actually manually coding onto a page. I just have enough experience with GTM now that it’s become obvious that it doesn’t really replace coding, it just supplements it, in tons of great ways.

    I hope you don’t give up on it, I really think it’s worth it.

  • Geo


    I really appreciate the response!

    I definately get your point about the multiple domain scenarios and the old static sites. Lack of dev sites is a pain, indeed, another point for GTM.

    I get your point about developers as well. Being one I guess I have a much easier time doing GA related consulting than most people. I mean, I do have a case when an implementation instruction of literally *one line* was implemented completely the wrong way, but usually I have few problems with devs.

    I think you’ve made a good case for GTM here. I’m beginning to think that maybe I’ve been blessed with some really excellent clients over the years as I can’t really point to scenarios as problematic as yours.

    “I love the GA Debugger extension, though I hate when it sometimes doesn’t load or work and I have to click and reload the page a few times.” – it’s the norm for me, LOL.

    Again, thanks, I may in end try and push a bit more in the GTM direction.

  • Interesting post, Sayf!

    It’s funny how sometimes tagging solutions like GTM force us to look at markup in a new way, isn’t it? 🙂

    With data- attributes, one cause for concern is if you leverage JS libraries which make use of data attributes which happen to be similarly named. This is perhaps marginal, but I’ve seen it happen with other forms of markup (e.g. “reserved” style declarations).

    As to the really interesting GTM discussion in the previous discussions, tag management has completely spoiled me. I don’t really see myself doing GA implementations (or any other tag setups) without using a TMS. There’s a simple reason for that: I’m future-proofing my tagging and JS use. I find it far more sensible to leverage a centralized interface for all tagging than to maintain bits and pieces of code scattered around a complex website.

    I think the main benefit of a tag management system is the word in the middle: management. Being able to visualize tags, their relation with arbitrary variables and values (e.g. macros in GTM) and the triggers that make these tags go off makes me a better developer. I now see redundancies where I wouldn’t have known to look for before, I see ways to make JS neater and leaner by using shared function calls (macros, again), and using a data layer is something I would do any way even if there wasn’t a TMS involved.

    And as for future-proofing, it’s really so much easier to understand how a new script or library fits into the general infrastructure of website tagging, when you can look at it in the context of all your tags. That’s one of the reasons I love working with a TMS.

    But I’m biased since, like I said, I’ve been spoiled by great clients and a wonderful tool 🙂 There are definitely things that should be improved upon, but often it’s not just the TMS fault but rather crappy markup, obscure JS resources, or the Microsoft stack (SharePoint, ePiServer…) which cause problems.

  • Sayf Sharif



    It’s funny you mention that about custom data attributes. One of the reasons we started leveraging them, was because we had a number of clients unable to modify their class or id attributes for us to recognize additional information about the elements, so we started using data attributes. It’s a good note to always be mindful of namespaces.

    Great points about tag management and GTM, thanks for adding your thoughts.

  • Ollie

    Nice Post, custom dimensions are very interesting I am always needing to find further uses of macros!

    One thing however, you don’t need to create your own macro to test whether the link clicked is a document. I would recommend using the built in function and add a {element url} to the rule matching regex (.pdf)|(.doc) to test if it is not a webpage. That way it won’t need to process a custom script. 🙂

  • Sayf Sharif


    Excellent idea!

    I think my mind got caught in a loop because I had initially set this up for a client with a Macro because we had some other things going on than just tracking docs, and needed to reuse the Macro itself in several places, and couldn’t do it the way you’re describing, but this is even better for simple solutions, where you want to keep your macros/tags/rules to a minimum.

  • Anthony

    In your example using data attributes. Are you required to add any additional code for this on your website? Or is this all purely done inside of GTM?

    Are there any browser limitations when using “gtm.element.dataset”?

  • Sayf Sharif

    Anthony, per the section above “What are Custom Data Attributes”, the actual attributes need to be added to elements on your website. Other than that though, no, the rest can be done in GTM.

  • Klaudio

    What about perfomance?

    Great post. I am working on a large website and I’m in a need to track 50 different elements across the site.

    My initial thought was to use data-attributes to target elements as they are “markup friendly”. However, after some research i came to realize that I would need a custom JS to recognize that data-attribute since there is no built in macro for them.

    So my biggest worry is performance, since i will need to track up to 30 elements per page and not only does it need to go through gtm but it also needs to go trough custom JS which only adds on the weight.

    My solution is to just add custom classes for those elements with a prefix “gtm-” so they are only used as hooks for gtm and use the classes macro to pick them up.

    What do you think about this? Is it better or is it safe for performance to go with custom JS for data-attributes?

  • Sayf Sharif

    Yeah absolutely, Klaudio. If you want to do groups of items you can do it several ways. Classes with prefixes, or even ID’s with prefixes and just lookign for those. Like tagging every image with an id of “img-XXXX” and you can easily reference all of them, etc.

  • I will try this techniques to track outbound links

  • Audrey

    I’ve searched high and low for exactly this article. Thank you for writing it!

    However, I’m a bit confused as to the difference between using the custom data attribute and simply using a dataLayer.push to get the attribute as a data layer variable for the macro.

    For example, here: How To Score
    Couldn’t you have done: How To Score ?

    Or am I completely missing the point?
    Thanks a lot!

  • Sayf Sharif

    Audrey, those links look the same, so I’m not sure what you were looking to show. (maybe it stripped out your code).

    Could you put a datalayer.Push inline in the link to push in values (assuming that’s what you mean)? Sure. Then your code would be inline, and maybe there would need to be a change. Also if you pushed in something like “sport” as a value to the datalayer it would apply to anything else.

    By using the data attributes we’re giving just THAT element a value, which can easily be accessed via GTM. No need for inline code sending events we might want to change in the future, and no values in the datalayer for the page that belong to a single element. The attributes let us tag individual things with unique information, which we can then choose to work with, or not, in GTM.

  • Audrey

    Hi Sayf,
    Thanks for your quick reply.
    Indeed, the code was stripped out of the comment. So if I’m understanding correctly, if I added a dataLayer.push to send the “sport” as a value and put that bit of code within the link tag, that wouldn’t necessarily be associated exclusively to the link. Am I understanding correctly?

    Thanks a lot for your help.

  • Sayf Sharif


    You can certainly push values into the datalayer to be referenced on the click. This is essentially doing that, but they then can be referenced anywhere by anything which could lead to inaccuracies, while the data attribute is only associated with THAT element.

Contact Us.

Follow Us



We'll get back to you
in ONE business day.
Our Locations
THE FOUNDRY [map] LunaMetrics

24 S. 18th Street
Suite 100

Pittsburgh, PA 15203


4115 N. Ravenswood
Suite 101
Chicago, IL 60613


2100 Manchester Rd.
Building C, Suite 1750
Wheaton, IL 60187