Advanced Google Tag Manager Tips – Tracking HTML Video Elements

Hello and welcome back to another advanced tip for Google Tag Manager. Today, we will be discussing how to build a listener for tracking HTML Video interactions in a way that allows us to use the built-in video triggers that currently only support YouTube videos. This will require knowledge of JavaScript and specifically how to listen for and react to media events. Don’t worry though, we will be providing a full example that you can use to track your videos.


The HTML Video element was added as part of the HTML5 specification to allow you to embed video files on a webpage very easily, and new JavaScript APIs were released to make interacting with these elements as straightforward as possible. These new media APIs include Media Events that are sent when certain actions take place, like a video being played or paused. By hooking onto these events, we can trigger callbacks to be run as they fire exactly as we would to track clicks on a link or scrolling through a webpage. The events we will be looking at today will be:

  • play: Sent when the playback state is no longer paused.
  • pause: Sent when the playback has been paused.
  • ended: Sent when the playback has completed.

To listen for these events, we will need to add our listeners to the video element itself:

Website code for Google Tag Manager

Within our listener callbacks is where we can set up our calls to push the event and its metadata to the dataLayer so that we can trigger our tags. Before we set those up, let’s review the payload GTM sends to the dataLayer for YouTube videos so we can structure ours in a similar way


Back in 2017, Google Tag Manager released native support for tracking YouTube videos including a new trigger type and some built-in variables. Clearly, this was a big win for those looking to track YouTube embeds without additional code, but it cleverly also provided a clean event payload schema for those looking to track other types of embeds in a similar manner. Let’s take a look at what an example payload looks like for a YouTube video:

Website code for Google Tag Manager

By modeling our event payloads using this same schema, we can take advantage of the native trigger and variables – so let’s get back to our HTML Video Listener.


As we discussed previously, to hook into the media events being emitted, we will need to add an event listener directly to the video element and within the callback we will send an event to the dataLayer using the schema definition above. Let’s take a look at an example for the play event:

Website code for Google Tag Manager

In this example, we are pushing an event to the dataLayer after the video element has emitted the play event. As part of this payload, we are indicating the status of the video as start, since play is currently not an accepted option for the schema. We are setting the URL to the src of the video element, but, do note, you may need to read this from the child source element if you are providing video in multiple formats. We have omitted video title, but if you would like to include a title, I would recommend adding a new data-* attribute to the <video> and then accessing it via JavaScript. Example:

Website code for Google Tag Manager

Website code for Google Tag Manager

The event listeners for the pause and ended events will follow the same setup. Let’s take a look at how we can extract our listener callback so we are not duplicating ourselves over and over:

Website code for Google Tag Manager

By extracting the callback to its own defined function, it allows us to use it with all of the listeners we need to add.

The example above is a fully working media event listener, but it has one potential issue, it will only track the first video on a webpage. What happens when we need to track multiple videos on a single page? Well, since we are working with native HTML elements, we can simply first select all of the videos from document and then loop through them to add our listeners:

Website code for Google Tag Manager

Now we are listening for the playpause, and ended events for every video on a single page. With the listener code completed, let’s get it added to Tag Manager and walkthrough how to set up the trigger and variables.


In Tag Manager, we will first want to enable the variables that we will be needing:

Website code for Google Tag Manager

Once these have been enabled we can add our listener as a custom HTML tag:

Website code for Google Tag Manager

This listener tag needs to fire on all pages that contain a video that needs to be tracked. We do not typically recommend firing tags on pages that don’t require them, but in the case of the listener, you could fire this across all pages if there’s no way to filter by those with a video. We would also recommend firing them using the DOM ready trigger type to be sure the elements have been added to the page. Note that we have wrapped our code in an Immediately invoked function expression or IIFE so that we are not adding our function and variables to the global namespace.

Now the listener tag is only responsible for pushing our video events to the dataLayer. We will need to set up a new YouTube Video trigger to fire the tags responsible for tracking these events.

Website code for Google Tag Manager

With the trigger setup, it can be added to any tag used to track video interactions, like an event tag for Google Analytics.


To recap, we have created a simple, reusable listener that we can add to any of our containers to track HTML video embeds using the native trigger and built-in variables. Will you be using this in your containers and are there any additional events you would like to see be handled by our listener? Let us know in the comments. If you would like any assistance with implementing tracking in Google Tag Manager, please reach out to our Data Intelligence Team and we will be in touch.

Github Gist: HTML Video Listener

Author avatar
Nicholas Hoium
Nicholas was FoundSM’s first employee. He primarily implements Web Analytics software; constructs ETL solutions for internal and external dashboards and reports; and develops internal web applications and APIs for lead management.