ClickCease

Tracking HTML5 Videos in Google Analytics 4

Tracking HTML5 Videos in Google Analytics 4

While Google Analytics 4 offers built-in 'Enhanced Measurement' for videos, it only natively tracks embedded YouTube videos. For self-hosted HTML5 videos (<video> tags) or other custom players, your data will be blank unless you have a custom setup like the one detailed below.

Google Analytics 4 does not track HTML5 video interactions by default. To capture events such as video_start, video_progress, and video_complete, you need to add JavaScript and configure Google Tag Manager. This guide outlines the steps required to granularly track custom HTML5 video elements, provided you can deploy a Google Tag Manager container.

Tracking video interactions helps you assess the performance of your video content. 

This approach can answer questions such as:

What’s the percentage of all videos that are watched till the end? 

GA4 report showing video_progress, video_start, and video_complete event counts.

The answer: 15 / 43 * 100 = 35%

What’s that number for easy specific video

Note: to run this test I created two test videos and named them Bunny Rabbit and The Earth, and asked good folks at Slicedbread to play one of the two videos. 

GA4 report comparing event counts for Bunny Rabbit and The Earth videos.
  • Bunny Rabbit: 5 / 26 * 100 = 19%

  • The Earth: 10 / 17 * 100 = 59%

Clearly, The Earth video is the one that was watched till the end more often. It is because it is the shortest of the two. 

What’s the most watched video of the two?  

GA4 report comparing total event counts for Bunny Rabbit and The Earth videos.

The answer: Bunny Rabbit

How many users watched different portions of the video? 

GA4 report showing video progress percentages and event counts for the Bunny Rabbit video.

You can use this information to assess the effectiveness of your video content, such as whether the video's length or content is engaging enough to retain viewers' attention.

Which traffic channels generate the most videos? 

GA4 report of video_start events by traffic source and medium.

If you treat a video playback as a micro goal on the way to a purchase, then knowing which traffic channel drives the largest number of video_start events could serve as an indicator of traffic source quality. According to the above chart, the Referral traffic did pretty well and might deserve an advertising budget increase. 

The insights above represent only the surface of what is possible with HTML5 video tracking in GA4. If you are ready to enhance your video performance analysis, here is how to begin the implementation.

How do I know that my video is an HTML5 video?

Your video is an HTML5 video if it uses <video></video> tags, such as those shown in the below HTML snippet:

    <div class="video_container">

      <video id="myVideo" width="320" height="240" controls>

        <source src="./assets/video.mp4" type="video/mp4">

        Your browser does not support the video tag.

      </video>

    </div>

If that’s what you have on your page, then this guide can be of help. You can learn more about the HTML5 video at this w3schools.com guide

What are CSS selectors?

To use the JavaScript code provided below, you will need to be able to update it with a CSS selector. For example, the correct CSS selector for the video element of the above HTML code is #myVideo. To learn more about CSS selectors, check out this guide:

https://www.w3schools.com/css/css_selectors.asp

Alternatively, make sure that your video tag is updated with an ID attribute, like so:

<video id="myVideo"></video>

Should I use the Autoplay attribute?

The HTML5 video can be added an autoplay attribute, which will make the video play automatically, as soon as a user comes to the page and the video is ready to play. This is accomplished by adding an autoplay attribute, like so:

<video autoplay id="myVideo"></video>

Sites that automatically play a video with an audio track can be an unpleasant experience for users, so it should be avoided when possible. As such, if you have that attribute, it is best to remove it. 

How do I add a JavaScript file to my site?

Almost every HTML page consists of the following elements:

<!DOCTYPE html>

<html lang="en">

<head>

  <title>Document</title>

</head>

<body>

  ...

  More code goes here

  ...

  <script src="/track-videos.js"></script>

</body>

</html>

If you were to save the JavaScipt code listed below in a file track-videos.js located at the root level, you would need to link to it by placing a <script> tag immediately before the closing </body> tag, as shown above. 

If the above still does not make sense, consider reaching out to someone who knows a bit more about front-end web development. 

The actual JavaScript code

The following code will work as is if your <video> tag has an ID attribute of myVideo, like so:

<video id="myVideo"></video>

If you cannot make sure the video tag has that specific ID attribute value, you will need to find and replace each instance of #myVideo with whatever ID attribute value your video has. For example, if your ID attribute is:

<video id="something_else"></video>

You will need to find and replace every instance of #myVideo with #something_else. There are only two places in the below code where that replacement needs to be made. Hopefully, that makes sense. Also, notice that closer to the end of the code there is a line of code that reads My Tracked Video. You can replace that value with something more specific to what your video is about. Just make sure it is below 100 characters, as that’s the maximum parameter value length in Google Analytics 4. 

For example, if the video you want to track is about a bunny rabbit, just use those two words in place of the My Tracked Video. With all bases covered, here comes the JavaScript code you will need to customize slightly (as described above) and save in a file such as track-videos.js:

(function(){

  'use strict';

  class HTML5Video {

    constructor(videoElemSelector, videoTitle){

      this.videoElem = document.querySelector(videoElemSelector);

      this.videoTitle = videoTitle;

      this.secondsPlayed = 0;

      this.percentagePlayed = 0;

    }

    initialize(){

      this.videoLengthInSeconds = Math.round(this.videoElem.duration);

      //enable progress tracking only where it makes sense: where video is long enough

      if (this.videoLengthInSeconds > 119){

        this.trackVideoProgressEvent = true;

        this.reportProgressAt = [10, 25, 50, 75];

        this.alreadyReported = [];

      }

      this.videoElem.addEventListener('play', () => {

        //'play' event is fired both when video is played and resumed

        //we want it to fire only once when the 'play' event fired the first time

        if (!this.videoPlayed){

          this.updateDataLayer('video_start');

          this.videoPlayed = true;

        }

      });    

      this.videoElem.addEventListener('timeupdate', (e) => {

        //tracks video progress event for videos 2 mins and over

        if (this.trackVideoProgressEvent){

          this.trackPlaybackProgress(e);

        }

      });

      this.videoElem.addEventListener('ended', () => {

        this.updateDataLayer('video_complete');

        //if video playback is started from scratch, make ...

        //...'video_start' event possible again

        delete this.videoPlayed;

        if (this.trackPlaybackProgress){

          this.alreadyReported = [];

        }

      });

    }

    trackPlaybackProgress(e){

      this.secondsPlayed = Math.round(e.target.currentTime);

      //calculate percentage progress every new seconds

      this.percentagePlayed = Math.round((this.secondsPlayed / this.videoLengthInSeconds) * 100);

      //ensure we report on each threshold only once for each percent listed in this.reportProgressAt

      if (this.reportProgressAt.includes(this.percentagePlayed) && !this.alreadyReported.includes(this.percentagePlayed)){

        //notify analytics

        this.alreadyReported.push(this.percentagePlayed);

        this.updateDataLayer('video_progress');

      }

    }

    updateDataLayer(event_type){

      //grab dataLayer array, or initialize one

      window.dataLayer = window.dataLayer || [];

      const dataLayerObject = {

        'event': event_type,

        'video_title': this.videoTitle

      };

      if (event_type === 'video_progress'){

        dataLayerObject.video_percent = this.percentagePlayed;

      }

      dataLayer.push(dataLayerObject);

    }

  }

  document.addEventListener('DOMContentLoaded', () => {

    //ensure instance is created only on pages where video with provided selector is found

    const myVideo = document.querySelector('#myVideo');

    if (myVideo && myVideo.nodeName === 'VIDEO'){

      const clip = new HTML5Video('#myVideo', 'My Tracked Video');

      clip.videoElem.addEventListener('loadedmetadata', () => {

        clip.initialize();

      });

    }

  });  

})();

The code pushes event data along with parameters to the dataLayer, which will be used by Google Tag Manager to log events in Google Analytics 4. 

Videos that are shorter than two minutes in length (119 seconds and below) will fire only video_start and video_complete events. Videos two minutes and longer (120 seconds and above) will additionally send a video_progress event, along with the video_percent parameter. The video_progress will fire at 10, 25, 50, and 75 percent. That being said, you could easily customize it to other thresholds by adding this bit of code [10, 25, 50, 75]. If you wanted to track the playback progress at 20 and 40 percent intervals, you could replace the value in square brackets with [20, 40].

How to make sure the code works:

Hopefully, you know your way around in Google Tag Manager. If you don’t, check out this guide

Copy the URL of your site containing the HTML5 video you want to track and paste it into the Preview video. For example, my test HTML5 videos were added to Slicedbread’s homepage at https://www.slicedbread.agency/ (chances are, the videos are no longer there if you decide to find them). That’s the URL I will preview in Google Tag Manager: 

Google Tag Manager interface showing the Preview button and live version.
Google Tag Manager Tag Assistant prompt for connecting to a website in Preview Mode.

With the URL containing HTML5 videos pasted, hit the Connect button and play the test video. With the video still playing, head back to Google Tag Manager. The left sidebar section (event timeline) will get populated with multiple Video Engagement events, as shown below:  

Google Tag Manager event timeline showing multiple Video Engagement events being triggered.

If you don’t see that, chances are you did not add the correct CSS selector. 

Set up the GTM variables, triggers, and tags

The above JavaScript code merely updates the dataLayer object of a page. The actual video interaction events are not yet logged in Google Analytics 4. To make that happen, we will need to create the following.

GTM Variables

We need to create two data layer variables: 

Google Tag Manager configuration for the dlv_html5_video_percent Data Layer variable.
Google Tag Manager configuration for the dlv_html5_video_title Data Layer variable.

GTM Triggers

We will also need three GTM triggers:

Google Tag Manager configuration for the video_start Custom Event trigger.
Google Tag Manager configuration for the video_progress Custom Event trigger.
Google Tag Manager configuration for the video_complete Custom Event trigger.

GTM Tags

Last but not least, we will need three GTM tags:

Google Tag Manager configuration for the GA4 video_start event tag.
Google Tag Manager configuration for the GA4 video_progress event tag.
Google Tag Manager configuration for the GA4 video_complete event tag.

With all those GTM variables, triggers, and tags in place and published, open the same page with videos in the Preview again, and let the video play. You might want to switch to see GA4 tas specifically by selecting the G- tag:

ag Assistant interface showing a connected website, detected Google tags, and the summary view.

Longer pages will track these events:

  • video_start

  • video_progress (10%)

  • video_progress (25%)

  • video_progress (50%)

  • video_progress (75%)

  • video_complete

Here is what I see in the GTM having played a longer (two minutes plus) video:

Tag Assistant summary showing "Hits Sent" to Google Analytics, including video_complete, video_progress, and video_start events.

All six events fired as expected.

Videos shorter than 2 minutes will have just two events:

  • video_start

  • video_finish

It does not really make sense to track the intermediary points for pretty short videos: 

Tag Assistant summary showing Google Analytics hits sent, including video_complete, video_start, and Page View events.

Understanding Video Engagement and Enhanced Measurement

Since its release, Google Analytics 4 has introduced "Enhanced Measurement," which natively supports video engagement tracking for many platforms. This feature significantly simplifies the process by automatically collecting data for embedded videos that support the YouTube JavaScript API. When Enhanced Measurement is enabled, GA4 automatically tracks events such as video_start, video_progress, and video_complete without requiring additional custom dimensions or code.

Google Analytics 4 event count report table highlighting the blog_post_read event among others.

With that event, I would send two parameters for the author name and blog post category:

GA4 interface for selecting custom dimensions, such as "Blog post author" and "Blog post category".

With those two parameters registered as custom dimensions, we could easily learn about the most-read blog author at Slicedbread: 

GA4 Free Form report displaying event counts by blog post author.

For custom implementations like the one described in this article, you generally only need to register custom dimensions if you are using non-standard parameters. Because video_start, video_progress, and video_complete are now recognized as standard events within the GA4 schema, parameters like video_title and video_percent should theoretically be available in your reports automatically.

However, depending on your specific property configuration or the complexity of your custom HTML5 setup, you may still find that certain dimensions do not appear by default. For instance, while video_title is often captured, the video_percent dimension may occasionally require manual registration as a custom dimension to ensure it is available for Exploration reports.

GA4 interface for searching and selecting video-related dimensions, such as "Video Percent" and "Video Title".

Google Analytics 4 does not include a default dimension for Video Percent, so I registered it as a custom dimension.

Tracking HTML5 video events in Google Analytics 4 offers valuable insights into user engagement with your video content. By using the provided code examples, you can monitor video views, play rate, and video progress, and then use this data to optimize engagement and the user experience. Testing your tracking setup also ensures the data collected is accurate and actionable.

Remember that tracking video events is just one piece of the puzzle when it comes to measuring the effectiveness of your video content. By combining video tracking data with other metrics such as bounce rate, time on site, and conversion rate, you can gain a more comprehensive understanding of how your video content is performing and make data-driven decisions to improve it.

We hope this article has helped you get started with tracking HTML5 video events in Google Analytics 4. For further information on Google Analytics and digital marketing data tracking, please consult the Google Analytics documentation and other online resources.