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 LunaMetrics (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.

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 https://www.youtube.com/iframe_api library to the page.

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

  • event: 'gtm.video' - 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: 'https://www.youtube.com/watch?v=...' - 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 a video is first loaded, the page loads the YouTube API library:

<script src="https://www.youtube.com/iframe_api">

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 the first video is added to the site.

Again, if the video is 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.


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?