Auto-Event Tracking In Google Tag Manager

There is a new version of this post for GTM V2 here.

The Google Analytics Summit came and went, and thanks to the Live Stream, everyone could participate. We were treated to a rapid-fire selection of Google Analytics’ new features, and this post sheds light on one of these in particular: automated event tracking in Google Tag Manager.

Auto-event tracking introduces a nice feature, which does what tag managers ought to do: it provides functionality without HTML template editing. This isn’t always a good thing, since automation is usually generic and only works for a couple of viable scenarios, but especially for these generic use cases, this new feature is a great addition to GTM’s already impressive feature list.

Auto-event tracking has four different types of event listeners you can create:

* Click listener
* Link Click listener
* Timer listener
* Form Submit listener

A listener is a function which operates in the background. When creating the listener, you tell what operations it should wait for, and once these operations take place, the listener activates and fires any code within.

In this short tutorial, I take a look at the first three listeners. I’ll return to Form Submit listeners as soon as I have a functioning form I can work with.

Note that all these tutorials use Universal Analytics, but it’s easy to do the same in Google Analytics (the only difference is which tag you use to send the event to your account).

Timer Listener

This is the easiest, so I’ll start with it. If you’ve read my previous posts, it makes the whole concept of “Dwell time” a whole lot simpler, without having to employ custom HTML tags (the whole point of auto-event tracking).

What it does is set off a timer for X milliseconds. After the timer reaches the end, an event is pushed to the data layer, which you can then use as a firing rule for your Analytics event.

1. Create a new Tag with the following settings:
Auto-event tracking: the new timer tag
2. Create a new Universal Analytics tag with the following settings; remember to add your tracking code to the “Tracking ID” field, and if you want the event to count as a hit, set “Non-interaction” as False:
Send timer tag
3. Make sure you have a rule in place to fire this UA tag:
The Timer rule
4. Save container version
5. Publish container

Here you create a Timer Listener, which starts the countdown upon DOM load. As soon as the timer hits 30 seconds, the event gtm.timer is pushed to the data layer.

The Universal Analytics tag you created is set to launch as soon as the event gtm.timer is pushed to the data layer, so as soon as the timer goes off, the event is sent to your Analytics account.

And no custom HTML editing was involved. Just some tags and rules.

Remember to check that the implementation works by looking, for example, at the Network tab in Firebug:
Check that the dwell time works by using Firebug

Link Click listener

This is a bit more complex than the Timer listener, but it’s still much easier than what you had to do before with custom HTML code.

The scenario here is that I have a “Back to top” link on my site, and I want to track its clicks. This way I’ll know a) do people actually read my pages to the very bottom and b) do they have an urge to get quickly back to the top of the page.

This feature makes use of the Auto-Event Variable, which is essentially a macro that can be used to refer to, for example, the DOM element where a click occurred.

1. Create a new tag which listens to link clicks on your site:
Link click listener tag
2. Create a macro which identifies all element IDs on your site (by using the Auto-Event Variable):
Element ID macro
3. Create a new Universal Analytics tag
Send back to top link to Analytics
4. Make sure you have the correct rule in place:
Rule wait for links
5. Save container version
6. Publish container

Here you first create the link click listener. When set up to fire on all pages, it listens to all link clicks throughout your site. As soon as a link click occurs, it pushes the gtm.linkClick event into the data layer.

In the Analytics tag, the important part is the firing rule. See how you’re waiting both for the gtm.linkClick event and for the element ID macro to match a certain DOM element? This is to prevent the event firing when all links are clicked. Instead, now it identifies the DOM element ID (using the Auto-Event Variable of the macro) where the click event occurred (#backtotoplink).

So now you have an event sent each time the Back to top link is clicked. Remember, again, to check the Network data:
Back to top link sent in Firebug

Click listener

This is pretty much the same as the previous tutorial, but the crucial difference is that the Click listener listens to all click events on your page.

The scenario is classic landing page optimization: I have a (fictional) blog home page, where article headings are just plain text, not actual links to the articles themselves. I want to employ the click listener to check how many people try to click the heading in vain.

1. Create a new click listener tag:
Click Listener tag
2. Create a macro for all classes (we use this to identify the headings):
Macro for element classes
3. Create a rule which waits for a click to the .title DOM element:
Wait for click on heading class
4. Create a new Universal Analytics tag:
New Universal Analytics tag to send the heading clicks
5. Save container version
6. Publish container

Here the important thing is to create a rule which waits for the event (which means that a click has occurred, thanks to the Click listener) and which requires that the click occur on a DOM element with the class of title, which happens to be the class of the headings on the home page.

Check the implementation in Firebug:
Firebug verifies the event has been sent

Auto-event tracking conclusions

Well it’s a nice feature, that’s for sure.

At the moment, implementing listeners requires the following general steps:

1. Create a tag which acts as the listener and pushes the appropriate gtm event into the data layer as soon as the operation occurs
2. Create a tag which fires as soon as the gtm event occurs and sends the data to Analytics

If you want to be more specific, i.e. wait for clicks on specific DOM elements, you need to create a macro which binds the auto-event variable in the data layer.

I’d also like to see the auto-event variables as default macros (similar to {{url}}) in the system.

Auto-event tracking is a good addition to Google Tag Manager, and it removes a lot of hassle with custom HTML code. However, it’s no a be-all and end-all solution, and there’s still a lot of manual work involved if you want to do anything more complicated (cross-event dependencies, complex chaining of events and so forth).


  1. Stef says

    Nice article! One question. You want to track clicks on ‘back to top’ button. In the html on your site I see <a href=”#top” rel=”nofollow”>Back to Top ↑</a>… So which element are you using in GTM? I don’t see any relationship in your steps and the html code. Im a bit confused by here :)

    So let’s say I have a buttong with this code in it. <a href=”″ rel=”nofollow”></a>

    Can I use ‘outclick/’ to trigger an event?

  2. says

    Hi Stef,

    You’re right, I don’t have it in my site HTML (any more), since I was actually only talking about scenarios where these could be implemented, not my actual site.

    So if you want to track just one link, you need to identify it with one of the Auto-Event Variables that GTM offers.

    In your case, you’d have the Auto-Event Variable type “Element URL”, and when setting up the firing rule for the Universal Analytics tag, you’d have something like

    {{Element URL}} contains /outclick/

    Thank you for your comment! I had to edit the HTML you wrote since this crappy template doesn’t accept angle brackets without them automatically turning into code.

  3. says

    I actually tested this and it works just like I wrote above.

    So if you want to send only links which have a certain href, you’d first bind the Auto-Event Variable type “Element URL” to a macro, and then you’d add the href content as the firing rule as above.

    • says

      Hi Josh,

      Thank you!

      However, I completely disagree with you. No way is your post obsolete. Auto-Event Tracking is (yet) really simple and caters only to the simplest scenarios.

      Having an event container which can accept a multitude of variables as its parameters, and having the chance to chain and synchronize events properly is still something that Auto-Event Tracking lacks.

      So don’t worry :)

  4. PDF enthusiastic says

    Nice post mate! I’m quite noobie in the GTM world and I’m still wondering how you can track PDF clicks with GTM. I really appreciate it if u have easy solution to my problem and u r willing to share it.

    • says


      If you want to track PDF clicks, follow the tutorial above for Link click tracking, with the following modifications:

      1) In step (2), make sure the macro is of the type “Element URL” (and name the macro accordingly as well)
      2) In step (4), replace the “{{Element id}} equals backtotoplink” with “{{Element URL}} contains .pdf”

      Remember to change the event variables to something more descriptive, e.g.
      Event Category: Click
      Event Action: PDF
      Event Label: {{Element URL}}

  5. says


    I’ve followed the link click listener to a “T” but I cannot get it to fire on my page. I want to track navigation links and other links on my home page to view event flow, but I can’t get the tag to fire. Any ideas what I may be doing wrong?

  6. says

    Thank’s for a useful article.

    Regarding your “classes example”, can you think of a method to catch the Inner HTML of the element with the class name?

    Ex., let’s say I have 2 tabs on a page like this:
    Recommended ProductsOffers

    How to track if visitors are clicking on “Recommended Products” or “Offers”? This is pretty easy to track with ex. jQuery, but I can’t see that this is possible with GTM Auto Events. Or am I missing something?

    • says

      Hi Eivind,

      Try using the “element” Auto-Event Variable. It captures the entire element the user clicked on, so if you have, for example, <span class=”navitab”>Recommended Products</span>, upon clicking the “Recommended Products” tab, the “element” variable would be populated by “<span class=”navitab”>Recommended Products</span>”.

      After this, you’d have a firing rule which looks for the click event and {{element}} contains Recommended Products.

      I haven’t tested this, but according to the documentation, this is how it should work.

      • says

        Ok, I have implemented this type of tracking. It’s not “out of the box” to do it.
        This is going to track the value of the innerHTML of the span with the class “navitab”:

        1. Create a “Auto-Event Click Listener” Tag
        2. Create a “Auto-Event Element” Macro
        3. Create a “Auto-Event Element Classes” Macro
        4. Save and Preview. Check Console Log in Google Chrome. Click on the Element. Check dataLayer in Google Chrome Console Log.
        5. If you traverse the dataLayer in Console Log, you will find your gtm.element
        6. Create a Data Layer in GTM with this gtm.element, ex. gmt.element.firstChild.innerHTML
        7. Create a rule: event equals and Auto-Event Classes” contains “navitab”
        8. Create a GA Event Tracking Tag with this rule, and Category = Tab Clicks, Action = Home Page and Label = gmt.element.firstChild.innerHTML dataLayer.

        This will send the value “Recommended Products” as a Event Label to Google Analytics.

      • says

        Eivind, nice work :)

        This just goes to show that AEVs only get you so far. If you want to dig into the DOM data, you still have to resort to “traditional” methods.

        I misunderstood your original question, as I thought you meant how to distinguish between two different anchor texts when applying a firing rule.

      • says

        I see I had some writing errors, ex. gmt.element.firstChild.innerHTML should have been gtm.element.firstChild.innerHTML but I hope you get the point.

        Using this method I can get the innerHTML of all elements that have class=”navitab”. Ex. did they click on the tab with “Recommended Products” or did they click on “Offers”?

        Cheers, and keep up the good work Simo.

  7. JF says

    Hi EIVIND,

    I try to do about what you did but in a more general way: track every link clicks and for each of them, return the link text and the href value. How would you do that?

  8. says

    Hey man great post thanks for sharing!
    I been playing with this new function but I found that sometimes I cant get to work event tracking when I use Element Classes or Element ID all though I look in the source code and activate my rule on the gA event,
    why could this be?

    • says


      It’s hard to say without a concrete example. The auto-event variables (i.e. the macros you created for them, such as Element class) are given values the moment a listener picks up the occurrence it was set up for.

      So if you have a link click listener set to fire on all pages ({{url}} matches regex .*), as soon as someone clicks any link, the auto-event variables are populated by values which describe the link element that was clicked. Note that the auto-event variables only take aspects of the DOM element itself (i.e. link), so you can’t use them to refer to parent elements without some custom scripting.

      So if you’re not getting any content in the variables, you’re either:
      * forgetting to set up a correct event listener
      * using an auto-event variable as a listener rule (remember, the auto-event variables won’t work until AFTER the listener is fired, so you can’t use them as firing rules FOR The listener)

      Or there might be a legitimate bug in your setup, in which case I suggest you take this up in the Google Product Forums.

      • Nadia says

        Hi! Thank you for your great posts! Would you be able to help provide scripting for how to set-up an an ‘auto-event variable’ macro that pulls in the first populated parent class (not #)? Thanks!

  9. says

    I am not a “Techie” or a “Coder “so have followed the guidance available and set up a link click listener tag which I know is working as I have Google tag assistant installed.

    My question is how can I see the activity: a nice simple explanation about how to set this up would be appreciated. I have tried in Google Analytics without success.

    • says

      Hi Angie,

      If you’ve set up the tag correctly (so the events are being tracked), the best way to validate the setup is to check the Real-Time Reports in Google Analytics. There’s a report specifically for events that have been sent, so if you click a link on your site and you see an event in the Real-Time Reports, you’re good to go.

      You don’t need any setting up to get the Real-Time Reports working. You’ll find them in the main navigation menu of your Google Analytics view.

  10. says

    hi Simo,
    how would I go about tracking a from submission – I have multiple forms on the page, I want to track only a specific form with an ID.

    many thanks, great article

    • says


      Form submission tracking is just as simple as with any of the other listeners.

      1. Create a new tag of type Form Submit Listener
      2. Choose whether you want the tag to wait for up to 2 seconds before firing the event (if you know you have problems with form submission load times it would be wise to check this) and if the form has to validate before sending the data to GA
      3. Set your firing rule (url .* works for most)
      4. Create a new analytics tag of type Event
      5. Add {{event}} equals gtm.formSubmit as the firing rule
      6. Use the auto-event macros to refer to attributes of the form element

      So if you want to track only a specific form, you’d add {{element id}} equals JustTrackThis as the firing rule for the send event tag.

      Since the form submit listener is waiting for the entire form to be submitted, the element which is processed by the auto-event macros is the form itself, and not, for example, the submit button.

      This means that you can use the auto-event macros to refer to the form element. {{element id}} would get you the ID of the form (if any), {{element target}} would get you the ACTION of the form (if any) etc.

    • Eli says


      And it makes no sense if you fire the Google Analytics tag with a rule with two conditions:
      – {{event}} equals gtmFormSubmit
      – {{url}} equals the URL where the form appears


      • says

        You could use a rule with the following conditions

        {{event}} equals gtm.formSubmit
        {{url}} equals <url to a specific page, e.g. Contact Us>

        If you have many forms on your site, but you only want to track the one form on the Contact Us page. This is useful if you don’t have (and can’t add) an ID attribute to the form element on the Contact Us page.

        Naturally, the most reusable and flexible way is to have an identifier on the form (such as the ID attribute) that you can then refer to in your rules and in your other macros.

        Having an ID attribute becomes almost necessary, if you have more than one form on your page, and you need to track them separately. If you don’t have ID attributes in your separate forms, you’ll need to identify the correct form using needlessly complex methods such as DOM traversal.

      • Eli says

        from your response, I’ve been trying things and I think I’ve clarified concepts, but not simpler.

        I still have some inconsistency but I will correct. Anyway, how that affects the code of Google Tag Manager is not put in the recommended site?

        You’ve been very helpful. You won a reader :)

        Thank you!

      • says

        Thanks Eli,

        I didn’t really get your question (if there was one), so if you need clarification for some things, you can just send me an e-mail and we can continue the discussion there.

  11. Jeremy says

    Is it possible to use the form listener to pass a user’s text input in a form field along to universal analytics?

    • says

      I don’t think you can do it with the form listener (since the gtm.element refers to the entire form). If your form field has a unique ID attribute, you can create a Custom JavaScript Macro which is like:

      function() {
      return document.getElementById(“fieldID”).value;

      And add that to one of your event fields. The macro returns the value the user input into the field with the ID “fieldID”.

      • says

        Hey SIMO,

        Thanks so much for your help. I’m also wondering how to use the form listener to pass a user’s text input in a form field. How do I know if my form field has a unique ID attribute?

      • says

        You’ll have to look at your page template code to see if the field has an id attribute (e.g. <input name=”Name” id=”fullname”..>).

  12. says

    Hi SIMO,

    Thanks for the reply! I found the field ID, but I get this error now if I try to preview in GTM:

    1. JavaScript Compiler Error input Error at line 3, character 32: Parse error. illegal character.
    2. JavaScript Compiler Error input Error at line 3, character 33: Parse error. missing ) after argument list.
    3. JavaScript Compiler Error input Error at line 3, character 52: Parse error. illegal character.
    4. JavaScript Compiler Error input Error at line 3, character 53: Parse error. syntax error.

    Any ideas?

    • says


      Looks like you either have a typo or some formatting is passed along when you copy-pasted the code. Make sure you copy-paste the code via notepad (or some other formatting-free tool) before inserting it in GTM.

      • says


        Thanks for the quick reply. I tried pasting in notepad first and then GTM but still getting the error. Weird. I’m adding your code as a custom javascript in the “Action” section of the event tracking. Wonder what I’m doing wrong!

      • says


        I’m confident this is a formatting error, since there’s absolutely nothing wrong with my code :)

        So if you’re copy-pasting this code into a Custom JavaScript Macro, which you then refer in an Event Action field of a GA tag, just try the manual tact. Instead of copy-pasting, write the function code letter-by-letter into the Custom JavaScript Macro.

        I’m guessing it’s the double quotation marks (“fieldID”) that are being misread by the tool.

        If this doesn’t work, please give view rights to your container to simo.s.ahava (at) and I’ll check what’s wrong :)

      • says

        Thanks so much for your help! I’ve been doing everything you’re suggesting, but it’s just not working! I gave you view rights. Thanks so much!

  13. Tiaan Van Zyl says

    Good Morning Simo (it’s morning in South Africa),

    We have recently introduced tag manager to our own website as a test before implementing it on our client’s profiles. So we are fairly new in the GTM game, so I will be reading a lot of your blogs.

    Here is my question:

    We have an ‘about’ section on our site with pictures of employees. When you click on a picture, a profile of the employee appears to the side of the picture. This does not direct you to a new page. How can we identify which picture has been clicked on via GTM? I have created the basic click listener, but what will I have to implement for the click listener to determine which of the pictures were clicked on?

    Thank you

    • says

      Hi Tiaan,

      This is where the auto-event macros step in. If you want to send an event every time an image is clicked, you’d need to create your event tag so that it’s fired when {{event}} equals

      The problem with this is that it fires the event with every single click that occurs on your page, so you’ll need to narrow it down.

      If your images have unique ID attributes (e.g. <img src=”rebecca.jpg” id=”rebecca_img”/>, you can just have a rule with two conditions:

      {{event}} equals
      {{element id}} equals rebecca_img

      If you don’t have an “element id” macro pre-made, you’ll need to create one yourself following the guide above.

      If you don’t have unique ID attributes for images, you can use an auto-event macro to pin down the image filename. So if your image tag is like <img src=”/images/rebecca_portrait.jpg”/>, you can follow clicks to that image with the following two rule conditions

      {{event}} equals
      {{element url}} contains rebecca_portrait.jpg

      This will send the event every time a click occurs on a tag whose href/src/action attribute contains “rebecca_portrait.jpg”.

      So if you have your click listener firing on all pages, and if you know how to create a basic Send Event tag, all you’ll need is a rule with two conditions: {{event}} equals, and a specifier, which you create using the auto-event macros.

      • Tiaan Van Zyl says

        Thank you very much for the clear and quick response. Just a quick question (again) – would this differ for a WordPress file? I seem to find the source code for the profiles on the webpage, but neither the element url or element id works with these? Any suggestions for this?

      • says

        Hi Tiian,

        I just tested your site, and your click listener is working perfectly, so every time I click a picture, I see some stuff pushed into the dataLayer. For example, if I click Nadia de Vries’ image, the following is pushed into the dataLayer object:

        event: “”
        gtm.element: [Object]
        gtm.elementClasses: “attachment-post-thumbnail wp-post-image”
        gtm.elementId: “”
        gtm.elementTarget: “”
        gtm.elementText: “”
        gtm.elementUrl: “http://[SIMO: OMITTED]/wp-content/uploads/2012/10/Nadia-De-Vries1.jpg”

        So as you can see, Id, Target and Text are empty, since your images don’t have those. However, element url has the filename, which should be unique. So in your Send Event Google Analytics tag, you should have the firing rule (1 rule, 2 conditions)

        {{event}} equals
        {{element url}} contains Nadia-De-Vries1.jpg

        And that’s it. This sends the event every time an image is clicked, whose URL contains the words (case-sensitive) Nadia-De-Vries1.jpg.

        This basically means that you need a separate Send Event tag for every image you want to track. You can overcome this with some clever macro use, e.g. create a macro which only grabs the filename (e.g. Nadia-De-Vries1.jpg) and uses that as the Event Action (so your event would look like “Profile Link Click” / “Nadia-De-Vries1.jpg”). Then you’d make sure the event is sent only on your profile pics by having the following firing rule (1 rule, 3 conditions):

        {{event}} equals
        {{url}} matches regex ^/about/$
        {{element tag type}} equals IMG

        You’ll need to create an “element tag type” macro as a data layer variable macro “gtm.element.tagName”.

        Now this elaborate explanation was for the benefit of other readers, who might want to track only specific image clicks. If you want more help with this, it’s probably best if we continue over e-mail, so drop me a line at simo(at) and I’ll help you get it sorted :)

  14. Mustafa says

    Thanks for the valuable info Simo. Really helpful.

    Can you talk about some uses of the Timed Interval Listener. Can it be used for video tracking? In your opinion what is the best practice for embedded (non-youtube) video tracking?


    • says


      If you’re happy with just calculating intervals of watched video, then you could use the Timer listener. You’d need to set the listener up so that it fires only upon Play. With Pause or Stop you’d need to halt any event that might be sent with the listener. However, if someone then clicks Play again, you’d probably lose track of just how much video was watched.

      For embedded videos, so much depends on the player you use and the available API. If the player has discreet buttons for Play and Pause that you can latch onto with a click listener, you can get pretty good measurement out of the video. Sometimes the API provides you a lot of stuff you can attach your events to (e.g. Wistia).

      An optimal solution would be something like:

      1) Calculate video length into segments (e.g. 5%, 10%, 15%, 20%, and so forth)
      2) Fire event upon first click of Play
      3) Fire event upon reaching a set segment
      4) Fire event upon click of Pause, make note of current position
      5) If video Play is resumed, continue firing segments in order

      Your events would then have the video URL, meaning you could see how often a video was played, paused, and how much visitors watched.

      You can’t really get this logic with the Timer listener. The Timer listener is best suited for measuring stuff like dwell time or something similar. Anything that can’t be paused and resumed, or that doesn’t require detailed and granular measurement. Though that’s just my opinion. I might lack the imagination to come up with more uses for it :)

  15. Jacob says

    First great posts I am learning more from you than Google. I have something I am trying to figure out and have spend many hours researching but not finding a clear resolution. So I would like to find a way to track when people click on a phone number with a smartphone.

    I have been adding a href=”#” just to try and get it tracking the click event but I am missing something. I have the container and the GA pageview code all working.

  16. Alex says

    Hello Simo,
    Wondering why replacing “Auto Event-variable” with {{element classes}} gives the same results? What is the difference between them?

    • says

      Hi Alex!

      I’m not sure I follow you here. {{element classes}} is one type of Auto Event Variable Macro. It targets specifically the CLASS attribute of the clicked element. So if the element is e.g.

      <a href=”” id=”myLink” class=”myClass”>

      {{element}} captures the whole link object
      {{element id}} returns “myLink”
      {{element classes}} returns “myClass”
      {{element url}} returns “”

      Is this what you were after?

      • Alex says

        Hi Simo,
        Thanks for your prompt response!
        What I meant was how these two variants may correlate – please see this screenshot
        I get same results in both cases. Just trying to understand what is the difference between these two scenarios?
        Thanks in advance for any info.
        Kind regards,

      • says

        Hi Alex,

        Oh I think I get it now. {{element classes}} and {{AF Auto Event Classes}} are the same thing. Both are configured as:

        Macro Type: Auto-Event Variable
        Variable Type: Element Classes

        {{element classes}} is just a pre-defined macro for you. GTM creates a bunch of macros with every setup to help you along.

        Because of this, you could delete {{AF Auto Event Classes}} because it’s an exact duplicate of {{element classes}} and thus redundant.

        If you want to read more, I wrote a bit about element type and element instance in my Macro Guide. The point here is that you can have as many instances of a macro type as you want. “Auto-Event Variable” is the type in this case, and {{element classes}} and {{AF Auto Event Classes}} are the instances.

  17. says

    Great articles, thank you!
    With your tips for tag manager my site’s bounce rate changed greatly using 15 second timer as you wrote. The other one “profit” – my both tracking systems: yandex and google now count visitors and bounce rate similar to each other!

  18. says

    Hi Simo,

    I’m trying to put a track event (in GTM) on a video which is embedded via iframe from YouTube.

    So far, here’s what I’ve got set up in GTM:

    1) a click listener set up for all pages
    2) a tag set up with a firing rule with the following conditions:
    {{event}} equals “”
    {{element id}} equals “IGBvideo” (this is the id of the iframe element)

    So far, it’s not returning any click event data to GA. The video is at the bottom of the home page at:

    Thanks in advance!
    John :-)

    • says

      Hey John,

      Unfortunately the clicks occur WITHIN the iFrame element and thus can’t be registered in the parent window. That’s just the way that browser security works. Any click within the iFrame is registered in the frame, and will not “bubble up” to the parent window.

      However, YouTube has an API which exposes events within to the parent window via API requests. Check Cardinal Path’s excellent guide on how to follow clicks on YouTube embedded videos:

      • Lorraine says

        Hi Simo,

        I’m trying to track clicks within an iframe too, mine isn’t a you tube video.
        I’m slightly confused on whether its ‘best practice’ to include the GTM script within iframes as well (and block other tags from firing in iframes with a blocking rule. What practices do you follow with this?


      • says

        Hi Lorraine,

        If you have your GTM container running in the iframe, it will track clicks and events to the dataLayer of the iframe, meaning any tags will fire just as usual. You will need to load the iframe using cross-domain tracking so that the events that occur within the frame don’t happen outside the currently active session. If the iframe src is on the same (sub)domain, cross-domain tracking shouldn’t be needed, as cookies are written on the highest possible domain name.

        The problem is that the clicks and events occur in the isolated environment of the dataLayer of the iframe. Thus, there’s no interaction with the dataLayer of the parent page, or its GA tags.

        The whole iframe thing, in my opinion, is a “worst practice”, but it’s still a necessary evil for many use cases.

  19. says

    Dear Simo,
    thnks to teach Tag Manager.

    I have a question: synchronous event are tracking?
    With dataLayer you can push event and other data in code.
    <select onchange="dataLayer.push({'event': 'myEventSpecialName'});" …

    in debug mode I can see in browser console the pushed event when I change the value of select
    Object, Object, Object, Object, Object: event: "myEventSpecialName"
    __proto__: Object…..

    but tag manager don't listen the change

    tag managr can linsten only click and submit? not change in real time?

  20. says


    Awesome article. I’ve set up both the All Clicks and Link Click listeners and they work great. Makes it super easy to track events as goals in GA without touching the code on the page. However a few elements that I want to track as goals either have an id or class. Easiest way for me to track I’ve found is just to pull all the events in GA and then pick the ones I want to use as goals.

    So: How would I set things up to track ALL element classes and ALL element ids in GA? I know how to set up the listener & rule, but how do I set up the macro for each? Thanks!

    • says


      You don’t need a separate macro. You should already have {{element id}} and {{element classes}} which are populated with the ID and/or CLASS of the target element when an auto-event takes place. Then you can just have a rule {{element id}} matches RegEx .+ or {{element classes}} matches RegEx .+ (and of course the event itself)

      This means that the rule is fired whenever there is any characters (must be at least one character) in ID or CLASS. So basically, if the element has ANY ID (Except blank string) or ANY CLASS (except blank string), the rule will fire and you’ll be able to view the data in GA.

      However, I suggest you consider not sending all clicks and links blindly to GA, but do some pre-filtering, sending only those hits which occur on elements you want to track. This can almost always be done, regardless of your markup. Soemtimes it requires a bit of a hack, sometimes it works like a charm with very little extra code.

  21. says


    Thanks for that reply. Have set up GTM to track the events on a site and then the goals in GA. Everything’s working perfect, tracking events and recording goal conversions. So awesome not having to even touch the code on the site to do this. Thanks again for the great post!

    Echo Internet Marketing

  22. says

    Just wanted to say thanks for the awesome tutorial. Brand new to GTM and got PDF tracking working (I think…preview works!) based on your walk-through. Will be exploring your site more to see what else GTM can do for me.

  23. Ronald Phillips says

    Great tutorials and blog posts, they’ve been very helpful!

    I have a question that is stumping me: We set up a click listener and a click action which is a custom html tag. The html is a script tag with a call to a js function. That function gets the actual event that was called and determines the click coordinates, the element that was clicked etc. Now this works fine in IE and Chrome, but FF does not have a global reference to the event (IE and Chrome allow “e = window.event”).

    Looking up the problem on google and it appears the only solution is that FF wants to pass the event object to the event handler, and they I can get what I need from that. But how do I do this using GTM’s click listener and click action? Basically I want to access the event object that should be getting passed to the handler. I hope I explained this sufficiently… Thanks!

    • says

      Hey Ronald,

      Good point about how FF exposes the event object. I can’t really think of any other way to hijack the event object except by hacking the GTM link click event handler and rewriting it to expose the event object in a global variable, for example. However, this is definitely not a very stable course of action.

      You might have to resort to a custom link click handler instead..

      • RFP says

        Thanks, Simo. That’s pretty much what we had to do, unfortunately. We lost some of the flexibility and ease of the GTM to our handler, but it at least helps us get most everything.

  24. says


    We have a appointment request form where the URL doesn’t change regardless if the user fills it out incompletely.

    For example, is the final URL for the successful appointment confirmations in which the user will get a thank you message after filling out the form completely and clicking “submit.” However, users who fill out the form incompletely and click “submit” will still see in the URL as it’s unchanged. How can I setup the event tracking in GTM to make sure we are only capturing the successful appointment confirmations in which the form was filled out completely and they user got the thank you message?

    Thank you,

    • says


      Have you tested this with the Form Submit listener? Even though the URL is unchanged, your form might still be built “correctly” in that invalid submits are registered by the listener as invalid (provided there’s the “check validation” option on the Listener tag) and not processed.

      The best thing would be to modify the form so that it works with tracking. Having a unique thank you page is good not only for tracking but also browser history states, as using the Back button with a single page application might result in multiple forms being sent accidentally.

      If nothing else works, then the ultimate hack is a DOM listener which listens for changes in the page, such as the emergence of a specific SPAN or DIV with the thank you message. Check this for ideas:

  25. says

    Hello, You resources are amazing and engaging on testing various features you are proposing. Thanks.

    My question is: Is it possible to use information from clicked element to set up my custom macro.
    For example:
    CLient clicked on button – Add to Cart. We want to find closest element to clicked element with ID=name. and put this in as macro in GTM.

    Is it possible to put event information in custom macro? (and build my own element macros)?


    • says

      Hey Janis,

      Yes it is possible. The {{element}} macro captures the HTML object that was the target of the event. In Custom JS macros and Custom HTML tags you can use this object as the starting point for DOM traversal.

      You can create your own element macros by creating a new macro of Data Layer Variable type. Prefix the macro with gtm.element and then use DOM properties to access other elements in the DOM tree (in relation to the clicked element). For example, the class name of the parent of the clicked link would be gtm.element.parentElement.className

      • says

        Thanks, Simo

        It was great help, looks like i am getting hang on it.
        Keep on rocking thease blogs.

        Hope you to see in Riga one day.

  26. says

    Hi Simo,
    Can you please explain how to track iframe embedded videos like Youtube. I have found some blogs but it seems that doesn’t work with iframes.

  27. says

    Hey Simo.

    Searched high and low, tried about 4 or 5 different tutorials.
    Yours was the only one organized and simple enough that I actually understood it – and it worked too :)


    P.S.: Do you have like a “GTM for Dummies” eBook?

  28. says


    Is there a way to track form submission with this tag,

    input type=”submit” value=”Nosūtīt” class=”wpcf7-form-control wpcf7-submit btn btn-default”

    I tried to track it using many ways, but it didnt work :(

    • says

      Forms are not tracked using the Submit button, because the form element is what’s stored in the dataLayer. So instead of looking at the input button, look at the FORM element itself for ids or classes that you can use in your rules.

      • lee says

        Hi Simo

        i’m having real issues with picking up a submit button ( the form class contains an ID “AddToCartForm” and I’ve tried various methods to pick this up. latest being a datalayer variable macro gtm.element.AddToCartForm but i just can’t get any value to show in the datalayer

        am i missing something obvious…

  29. Jaroslav Pilny says

    Hi Simo,

    I have encountered an issue while setting up GTM tracking for one of my e-shops. The thing is that I would like to track adding of an item to a cart. None of the listeners (Click and Link click) won’t track clicking the “Add to cart” link, however.

    Any idea where the problem might be?



  30. Marija says

    Hi Simo!

    Thanks for great articles!

    I have a question which i haven’t really managed to figure out.
    I have a pixel tracking on my site that appears only once after user action (button click). I need to calculate appearing of this pixel tracking, but I am not sure how. The only thing that is unique is tag <ns2:pixel.
    Any idea how i can solve this?

    Thanks :)

  31. says

    Hi Simo!

    I am having some serious trouble tracking clicks in my iframe. It is on a subdoamin. All of my shopping cart actions happen in this ifram so I really need to track clicks in here in order to give proper attribution to my marketing campaigns. Do you have any advice?

  32. says

    Hey Simo,

    So, I’m trying to track when people click on outbound links on a site (following I have set up an auto-event that tracks the click URL hostname, and then I defined a trigger that matches the desired URL hostname.

    So far so good, but when I clink on an outbound link the event doesn’t get the attributes of the clicked element (such as href). Why ? because for ex, an “a” element containing an href also contains a “span” or a “picture” element and GTM will get the attributes of the “span” or “picture” elements instead of the “a” element (which the parent of these). So the Click URL Hostname returned will be [object HTMLSpanElement]…

    Would you have any idea how to circumvent that?

    Thanks a lot in advance!


    • says


      Yes, this is exactly how the Click Listener works. In JavaScript, the event target is the object that was clicked.

      However, this is precisely why the Link Click trigger type exists. Did you try using that? It will propagate the click up to the nearest ancestral “a” element, and get all its properties for the variables.


  33. santiago says

    Hi Simo,
    Your blog is amazing.
    I have a slider in a hompeage that when clicked delclares a DIV element. There is no alt tag, text or similar populated in the console.
    How could I dynamically track that slider?
    Thanks a lot.

  34. Andrey says

    Hi Simo, I’m using Google Tag Manager to add Universal Analytics to a page and triggering an event with the JavaScript API. I’m able to the see the event being sent using GA Debugger and on the “Real-Time -> Events” page in GA but it never seems to make it to the “Behaviour -> Events” page (no filters or segments on). I also have noticed that when I observe the events on the real-time -> events page, they are saved on the behaviours -> top events page. Only if I see the events in real time first are they saved.

    Please advice.
    Thank you!

  35. Ivan says

    Hi Simo

    Great post. I’m thinking of the way to send to GA an event after a user has 30+ seconds SESSION.

    The problem is that timers are reset on every pageload and I can’t understand how I can make it work across pages.

    Any ideas?

    Best regards,

    • says


      It isn’t simple. Basically, you need to create a timer which goes off at 30 seconds. If the user navigates away from the page before 30s has passed, you will need to save the remaining time in a browser cookie or localStorage, and then restart the timer from where it left off on the following page.

      Quite complex and quite unreliable. There’s a reason GA moved from client-side to server-side sessionization with Universal Analytics – the browser is not very good at handling persistence and state.

  36. Shif says

    Hi Simo,

    I’ve been scouring the web for a solution to our website’s issue and was wondering if you could help.

    We use lots of 3rd party pixels that we’d like to move to a separate domain, and fire them using a GTM container within an iFrame on our parent site. This is to avoid any possible security issues from the pixels, by removing any & all access to our actual parent site.

    Our idea is to create a call to the iFrame based on events on our parent site, and load the iFrame with a changeable, ‘fake’ URL that will in turn trigger the different rules in the GTM, firing only the necessary pixels upon each load (i.e. different pixels for different events, etc).

    My question is, will we need to create a separate GTM account for the new domain, or can we just use a new container from our existing GTM account? (i.e. will the URL-based rules work for our domain’s GTM or do we need to create a new account + container for

    Please let me know if you think this will work and what would be the best way to do this :)



Leave a Reply

Your email address will not be published. Required fields are marked *

Please do not write HTML or other formatted code in your comments!