Last updated 20 April 2020: Clarified how lazy-loaded videos can be tracked with this trigger.

Let’s cut straight to the chase. Google Tag Manager has just released the YouTube Video trigger, which gives you native support for YouTube video tracking. And it’s great! Even though we’ve been more than satisfied with the excellent tracking scripts provided by e.g. Cardinal Path and Bounteous (with a small modification from yours truly), this is a no-brainer for native support in Google Tag Manager.

The YouTube Video trigger checks pretty much all the boxes I’d expect in a video tracking trigger. It has built-in events for things like Start, Progress (e.g. 25%, 50%, 75%), and Complete. You can also use it to decorate the embedded YouTube URLs with the required enablejsapi=1 query parameter, if they don’t already have it.

The YouTube Video trigger supports tracking lazy-loaded or dynamically inserted videos, too, which will be a relief to sites that defer loading videos until they are actually interacted with by the user.


The Simmer Newsletter

Subscribe to the Simmer newsletter to get the latest news and content from Simo Ahava into your email inbox!

Create and configure the trigger

To create the trigger, scroll to Triggers in the Google Tag Manager user interface, and create a new trigger. You’ll find the YouTube Video option in the sidebar that flies out when you click to choose a trigger type.

Once you’ve selected the YouTube Video trigger type, it’s time to configure it. Here are the options.

  1. Capture - Start - collects a start when the user starts watching the video.

  2. Capture - Complete - collects a complete when the user reaches the end of the video.

  3. Capture - Pause, Seeking, and Buffering - collects a pause when the user pauses the video or jumps forward or back, and buffering when the video starts buffering due to lack of bandwith.

  4. Capture - Progress - collects a progress the moment the user passes either a percentage or time threshold (e.g. 25%, 50%, 75% or 10 second mark, 30 second mark, one minute mark).

  5. Advanced - Add JavaScript API support to all videos - if your YouTube embeds lack the necessary enablejsapi=1 parameter, you can check this to automatically add it to all your videos. NOTE! This reloads the iframe, so users might see the video flicker when they first load the page. This option, when checked, also adds the required library to the page.

Here’s what the dataLayer payload looks like whenever a YouTube event is triggered.

  • event: '' - the event name pushed into dataLayer for all YouTube video events. This is what fires your YouTube trigger.

  • gtm.videoProvider: 'youtube' - specifies the platform whose videos you are tracking. You can take this as a hint that support for other platforms is planned!

  • gtm.videoStatus: 'start' - specifies the status of the video that caused the event to trigger. These different status values are only triggered if you’ve enabled them in the trigger settings. Possible values are 'start', 'complete', 'pause', 'buffering', and 'progress'.

  • gtm.videoUrl: '' - the original URL of the embedded video.

  • gtm.videoTitle: 'Best of Simo Ahava' - the title of the embedded video.

  • gtm.videoDuration: 197 - the total length of the video in seconds.

  • gtm.videoCurrentTime: 30 - the time mark where the user is at when the video event happened.

  • gtm.videoElapsedTime: 10 - the time elapsed since the last time the video was paused or buffering.

  • gtm.videoPercent: 15 - the percentage mark where the user is at when the video event happened.

  • gtm.videoVisible: true - either true or false, depending on whether or not the video was visible in the browser viewport when the video event happened.

One thing that might make you breathe easier is that there are new Built-in Variables for all these items in the dataLayer. You can find them by clicking the red CONFIGURE button when browsing to Variables / Built-In Variables in the Google Tag Manager user interface.

Quick word about progress tracking

Do note that tracking progress is relative to the entire video length and not the actual time or percentage you’ve been watching the video.

So if you configure the trigger to fire at 25%, 50%, and 75%, it will fire those events when the user reaches the respective marks in the video timeline even if they haven’t watched continuously from the beginning. Thus, if you start playing a video and jump straight to the 25% mark, the event will fire even though you only just started watching.

The same applies to the time thresholds.

You can leverage the Video Elapsed Time variable to see how long the user has been continuously watching the video since the last pause. Using the time and percentage thresholds only tells you if the user reached a specific milestone in the video, not necessarily if they actually watched all the way to that point. It’s a small but potentially significant difference.

Putting it all together

Since there are so many combinations of events you can collect with the YouTube Video trigger, I’ll show a fairly generic way of measuring start, pause, percentage progress and complete events with just one Universal Analytics Event tag. The tag looks like this:

The trigger that fires this tag looks like this:

And the Custom JavaScript Variable named {{JS - Get video action}} looks like this:

function() {
  var status = {{Video Status}};
  switch (status) {
    case 'start':
      return 'Start playing';
    case 'pause':
      return 'Pause';
    case 'buffering':
      return 'Buffering';
    case 'progress':
      return 'Reached ' + {{Video Percent}} + '%';
    case 'complete':
      return 'Reached the end';

This translates the default parameter values of the video object in dataLayer to a more readable format. Thus we can use the same Event tag for all video events.

Track lazy-loaded / dynamically inserted videos

If your videos load during the initial page load, then everything is smooth sailing for you. By checking the Add JavaScript API support to all videos option, GTM will take care of initializing the videos so that they can be tracked by the trigger. This option also downloads the required API library for you (see below).

However, more and more sites are performance-wary these days, and they defer loading any embedded content until the user has intimated that they want to watch the video. You can read about the technical implications here.

Luckily, the YouTube Video trigger does support tracking videos that are loaded and embedded after the initial page load. The only thing you need to do is make sure that when the page first loads, the YouTube iframe API is loaded as well:

<script src="">

So if your site does lazy-load or otherwise dynamically load videos (e.g. if it’s a single-page app), make sure that the library above is loaded before GTM’s video trigger is initialized. A “Page View” trigger usually does the job.

Again, if there is a YouTube embed video present during the initial page load, you don’t have to worry about this. The Add JavaScript API support to all videos takes care of loading this library for you.

The YouTube trigger does not work

If for some reason the trigger isn’t tracking your YouTube embeds, you can use the following method to investigate the issue.

  1. Check that the site has loaded the library.

  2. Check that the YouTube iframes have the enablejsapi=1 parameter in the src attribute.

  3. Check that the YouTube iframes have a parameter that looks like data-gtm-yt-inspected-XXXXXX.

If all three check out, it typically means that something on the site reloads the iframe after GTM has inspected it. When Google Tag Manager initializes the video trigger, it initializes the listener on the embed. Any reload of the embed removes this listener, and because the iframe has the data-gtm-yt-inspected-XXXXXX attribute, GTM doesn’t re-evaluate the listener.

Talk to the devs and make sure the iframes are not “recycled” (same iframe element used for multiple videos), and that once the iframe has been added to the site, it’s not reloaded for any reason.


I’m quite happy with the YouTube Video trigger. It does pretty much all I’d expect from the first iteration of the feature. I hope we’ll see support for other video services and players in the future.

There’s not a lot I miss. Mainly, I’d like for there to be a gtm.videoTotalElapsedTime, which would measure how much in total I’ve been watching any given video. The gtm.videoElapsedTime only tells me the elapsed time since the last pause/buffer/seek, but not what the total time watched has been.

What do you think of the YouTube Video trigger? Is it just perfect for your tracking needs, or do you have features in mind you’d want to see in a future release?