Upcoming LunaMetrics Seminars
Boston, Apr 6-10 Los Angeles, Apr 13-16 Atlanta, Apr 27-30 Washington DC, May 11-15

How to Track Hover Events with Google Tag Manager

hover craft joy ride with dolphins

When visitors hover on your website, are they more likely to convert? Pick a hover target and add event tracking to find out.

If you want to listen for clicks or form submissions, Google Tag Manager has some seriously awesome automatic event tracking. It doesn’t cover hover events yet, though. So if you want to track a visitor hovering over a menu or pop-up window or other such thing-a-ma-jig, read on for a nifty bit of jQuery that will do the trick.

Step 1. Include the jQuery library.

If your page doesn’t have jQuery, or the jQuery library is only included in the page source after your Tag Manager container code, then the code I’m going to give you won’t work.

First things first: make sure your page source includes the jQuery library before Tag Manager.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>



<!-- Google Tag Manager -->

<noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>

new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],

<!-- End Google Tag Manager -->


Typically, jQuery and other scripts are included in the head element, while Tag Manager appears in the body element. Your page source won’t look exactly like the above. It’s the order that counts. The jQuery library has to come first.

Step 2. Identify the hover element.

Tag Manager needs some information like a unique element name, class, or id (or unique combination of attributes) so it doesn’t try to track everywhere the visitor hovers on the page. Right-click on the page where you want to track the hover event, and choose inspect element.


In this example, I’m going to track when a visitor hovers over some text that says “Cart (1 Item)”. That action produces a pop-up window showing the contents of the shopping cart.

I inspect the element by right-clicking on it, and see the text is contained in a div element with the class “wl-cart-summary”.

page source showing hover target element

Because the class “wl-cart-summary” is unique to this element, I can use it to write a jQuery selector. The selector will focus the hover tracking on the cart summary pop-up.

Step 3. Create a Custom HTML tag and enter jQuery.

Open Tag Manager and create a new tag of the Custom HTML tag type. Enter the script shown below, and customize the jQuery selector $(“div.wl-cart-summary”) to match your hover target.

<script type="text/javascript">

$(document).ready(function() {

// Hover over Cart Summary
    var startHover = $.now();

        startHover = $.now();
        var endHover = $.now();
        var msHovered = endHover - startHover;
        var seconds = msHovered/1000;
        if (seconds >= 1) {
            dataLayer.push({'event': 'cart-hover', 'eventAction': {{cartText}}, 'eventLabel': {{url path}}, 'eventValue': seconds});



This code targets the div element with the class “wl-cart-summary” and listens for when a visitor starts hovering and also for when she stops hovering. It doesn’t send an event to the data layer until the visitor stops hovering.

The code also calculates the amount of time a visitor hovered, so you can decide whether or not she hovered long enough to make it worth tracking an event. Here I push the event to the data layer if the visitor hovers for at least 1 second.

I send all of this info to the data layer because I’ll need it in the next step, when I write my GA event tag:

event: cart-hover
eventAction: {{cartText}} = a custom JavaScript macro (how many items in cart?)
eventLabel: {{url path}} = a default macro (what page was the visitor on?)
eventValue: seconds = a variable from my code (how long did she hover?)

And then I fire this tag on every page since it’s part of the top navigation. You could use a more selective rule if you don’t need to fire it everywhere.

Bonus tip: The eventAction doesn’t have to be a macro; it could just be a word or phrase. But I wanted to get fancy, since the text of this element can change. So I created a Custom JavaScript macro in Tag Manager called {{cartText}} to reflect the number of items in the cart when the visitor hovered.

function() {
   var cartText = $(".wl-cart-summary a.cart-summary-trigger").text();
   return cartText;


The above macro cartText looks for an anchor with the class “cart-summary-trigger” inside an element with the class “wl-cart-summary” and returns the text of that anchor. (See the screen shot earlier from when I right-clicked to inspect the element.)

Step 4. Create a GA Event tag.

Finally, write a tag that will send an event to Google Analytics every time your cart-hover event gets pushed to the data layer.

Create a new tag in Tag Manager: tag type = Google Analytics and track type = Event.

Enter the information you pushed to the data layer in the Event Tracking Parameters, as shown below.


Then fire this tag with a new rule that says {{event}} equals cart-hover, or whatever event you pushed to the data layer.

If you haven’t already created the macros for eventAction, eventLabel, and eventValue, you’ll need to do that, too. Simply choose macro type Data Layer Variable and enter the same variable name that you pushed to the data layer, e.g. eventAction, etc. You’ll be able to re-use those macros with other events you might decide to track later.

Step 5. Update, Preview, Debug. Create New Version and Publish!

Test your tag to make sure it’s firing at the right times and capturing the right info. Then create a new version of your Tag Manager container and publish, and start collecting all that beautiful data!

How are you harnessing the power of Google Tag Manager? What events have you been able to track that aren’t covered yet by auto event tracking? Please share in the comments.

Dorcas Alexander

About Dorcas Alexander

Dorcas Alexander is a Digital Analyst working with Google Analytics. Her path to LunaMetrics included stints in ad agency creative, math, computer science, language technology research, and corporate training. She loves to learn and teach what she’s learned. One of the top-rated tournament Scrabble players in Pennsylvania, Dorcas has an insatiable drive to compete and win. “Impossible” is not in her vocabulary.


19 Responses to “How to Track Hover Events with Google Tag Manager”

RYan says:

Hi Dorcas,

Thanks for the post. This is great.

My event is firing, but the seconds is not working.

Within Analytics I am seeing the eventAction as gtm.js.
Any ideas?

RYan says:

dont worry! my code mix up

Dorcas Alexander Dorcas Alexander says:

Glad the code is working for you. Thanks for reading!

Felix says:

Hey! First of all: great post! realy!

But how can I adapt your code so I can track when visitor clicked on a “Add to chart” Javascript button?

That would be great help for me ^^

Greetings from Germany

Dorcas Alexander Dorcas Alexander says:

Hi Felix, I actually track that, too! When a visitor clicks the “Check Out” button on my hovered page element, I fire an event tag. The rule that fires the tag has 3 conditions based on the following: (1) a tag with the built-in click listener, (2) a macro that reads the target of the link, and (3) a macro that reads the button text. The specific rule conditions are: (1) “event equals gtm.click”, (2) “Auto Event URL matches RegEx /cart$” (i.e. the button target is the URL of my cart page), and (3) “button text contains Check Out”. I send a different event category (cart-hover-checkout) but the same action (cart text) and label (url path) as for my cart-hover event. Hope that helps!

Tuan Hoang says:

Hi Dorcas ,

(function (w, d, s, l, i) {
w[l] = w[l] || []; w[l].push({ ‘gtm.start':
new Date().getTime(), event: ‘gtm.js’
}); var f = d.getElementsByTagName(s)[0],
j = d.createElement(s), dl = l != ‘dataLayer’ ? ‘&l=’ + l : ”; j.async = true; j.src =
‘//www.googletagmanager.com/gtm.js?id=’ + i + dl; f.parentNode.insertBefore(j, f);
})(window, document, ‘script’, ‘dataLayer’, ‘GTM-XXXXXXX’);.
I’ve already had the GTM like above
By following your article, i just need to call the script below to track the event.
dataLayer.push({‘event': ‘cart-hover’, ‘eventAction': {{cartText}}, ‘eventLabel': {{url path}}, ‘eventValue': seconds});
But i don’t understand in step 4. You said:Create a new tag in Tag Manager: tag type = Google Analytics and track type = Event.And enter the information you pushed to the data layer in the Event Tracking Parameters.
How to create new tag in Tag Manager to track event. Please use your earlier example to continue the reply . Thanks a lot. I’m waiting for your response soonest.

Dorcas Alexander Dorcas Alexander says:

Hi Tuan, Sorry for the late reply. Make sure you are creating two new tags in Tag Manager: (1) the custom HTML tag with the entire script shown in Step 3 above, and (2) the Google Analytics Event tag. All the info you need to create the Event tag is in Step 4 above. Please let me know specifically which part you are unable to find, after you log in to your Google Tag Manager account, and I will see if I can help you some more.

Paul says:

Hi Dorcas,

Great post — thanks so much! We can fire the HTML tag with the conditional gtm.dom event to avoid requiring specific jQuery placement. In my specific case, jQuery must come after the GTM tag.

Thanks again!

Sean says:

Hi Dorcas.

Lovely article and just what i needed/wanted to find today. Thanks for sharing.

Just one question. I am wanting to track hover time on individual items within a collection. There are about 20 items in this collection that all have the same div class. Everything I’ve tried based on your cartText script has returned either “undefined” in GA or pulled in all of the text from each of the 20 items in this grouping. Is it possible to pull in an image title or alt text using the img portion of the code? This page is not dynamic, but I don’t want to have to write a different tracking code for each element.

Dorcas Alexander Dorcas Alexander says:

Hi Sean, You can definitely return an image title or alt text. For example, if the current image has the class “state-in”, then to return the value of the attribute “data-caption” try using the following jQuery: var mytitle = $(“.state-in”).attr(“data-caption”); return mytitle; Hope that helps!

Harry says:

Hi Dorcas,

thanks for the tutorial!
I tried to capture the hover time over our hotline in the top right corner.

Unfortunately I always get an error from your jQuery Script and I don’t know why:
Uncaught TypeError: undefined is not a function

This is what I got:

$(document).ready(function() {

// Hover over Hotline
var startHover = $.now();

startHover = $.now();
var endHover = $.now();
var msHovered = endHover – startHover;
var seconds = msHovered/1000;
if (seconds >= 1) {
dataLayer.push({‘event': ‘HoverHotline’, ‘hoverDuration': seconds});


I also checked the placement of the jQuery Script and the jQuery Version also has .hover as a function from what I could tell (http://api.jquery.com/hover/)

Any idea what I’m missing?

Dorcas Alexander Dorcas Alexander says:

Hi Harry, Did you wrap your code with script and /script tags? It’s hard for me to diagnose further without seeing what else might be running on the page.

Harry says:

Hi Dorcas,

I used Skript Tags, I think they were removed from my comment. You can check my page, I left the code online.
What’s bugging me is that Google Tag Manager obviously refactors the code into this:

$(document).ready(function(){var b=$.now();$(“h3.head-hotline”).hover(function(){b=$.now()},function(){var a=$.now(),a=a-b,a=a/1E3;1<=a&&dataLayer.push({event:"HoverHotline",hoverDuration:a})})});

Dorcas Alexander Dorcas Alexander says:

Hi Harry, I checked one of my own pages where I have this code running successfully and it is also minified the same as yours. I looked at the site named in your email address and did not find this code in GTM there.

Harry says:

Hi Dorcas,

I found the solution – as usual it was obvious :)
The jQuery Object wasn’t available as $. I simply had to rewrite the calling function:
jQuery(document).ready(function($) {

All working fine now, thx for your help!

Mike says:

Can you please explain the uses case of using the documentlayer type of event tracking using:

dataLayer.push({‘event': ‘Event BuilderSubmit’});

verse the ga send method:

ga(‘send’, ‘event’, ‘category’, ‘action’);

Dorcas Alexander Dorcas Alexander says:

Hi Mike, The ga send method is equivalent to using a tag in GTM, where the tag type is Universal Analytics and the track type is Event. Pushing an event to the data layer is useful for writing a rule to fire the GTM tag, because you can specify one of the rule’s conditions to be: event equals X (or, in your case: event equals Event BuilderSubmit). You would still need to enter the category and action in the GTM tag, or use a macro for category or action or both. Defining a macro allows you to grab the information from additional info that you write to the data layer with the event, or capture info that already exists on the page.

Mike says:

Thanks, Dorcas.
Let me make sure I understand.



dataLayer.push({‘event’: ‘Event BuilderSubmit’});

The real difference is the datalayer method while I still have to set up a Macro, Trigger and a Tag in GTM it gives me the added flexibility to capture other bits of info from the page from the datalayer or element id.

While the push method is quicker to code it only has the info that I write into the function call at the time.

Is this correct?

Dorcas Alexander Dorcas Alexander says:

Hi Mike, Yes, there is more flexibility with Tag Manager as opposed to inline code for the reasons you stated specific to event tracking, as well as the additional overall advantages you have with Tag Manager – serving multiple pieces of code asynchronously, version control, and built-in modularity. You don’t have to use a macro in your GTM event tag to send the category and action, but you’ll make the best use of GTM’s modularity if you do use macros there.