Wednesday, April 24, 2024
No menu items!
HomeData Analytics and VisualizationTrack Videos with Google Analytics 4 and Google Tag Manager

Track Videos with Google Analytics 4 and Google Tag Manager

Even though Google Analytics 4 offers some built-in video tracking capabilities, there might still be some cases where you will need to do additional configuration in Google Tag Manager. And I wanted to cover different situations, from simple ones to more complex ones.

In today’s blog post, I will show you how to track videos with Google Analytics 4 and Google Tag Manager. Let’s start with the Enhanced Measurement, then go to custom setup, then non-Youtube video players, and more.

 

Table of contents

+ Show table of contents +

So, what’s the plan?
#1. Built-in video tracking in GA4
#2. Youtube video tracking with GTM trigger and GA4
#2.1. Create a Youtube Video Trigger
#2.2. Enable built-in video variables
#2.3. Create a Google Analytics 4 tag
#2.4 Test the setup

#3. How to track Vimeo with GA4 and GTM
It all starts with identifying the video player
#3.1. Create a variable “Is Vimeo player present on a page”
#3.2. Vimeo Auto-Event Listener
#3.3. Create Data Layer Variables and a Custom Event Trigger
#3.4. Create a Google Analytics 4 event Tag
#3.5. Test test test
#3.6. The entire process in a nutshell

#4. Tracking HTML5 video player with Google Analytics 4
#5. Three GTM recipes for video tracking with GA4
Final words
Youtube video player tracking
Step 1. Create a Youtube Video Trigger
Step 2. Enable built-in Youtube video variables
Step 3. Create a Lookup Table variable
Step 4. Create a Google Analytics tag
Step 5. Test the setup

How to track Vimeo video player with Google Tag Manager (custom solution)
Identify the video player
Step 1. Create a variable “Is Vimeo player present on a page”
Step 2. Vimeo auto-event listener
Step 3. Create Data Layer Variables and Custom Event Trigger
Step 4. Create a Google Analytics tag
Step 5. Test the setup
To sum up

Six Google Tag Manager Video Tracking Recipes. All Unified.
Final words

 

Video tutorial

Prefer video content? Here’s a tutorial from my Youtube channel. However, keep in mind that this blog post contains additional tips and GTM recipes (readymade container templates).

 

So, what’s the plan?

First, we will take a quick peek at the built-in video tracking of GA4
Then we’ll take a look at the GTM setup that uses the Youtube Video trigger
Then we will take a look at a different video player (Vimeo)
Then I will show how to track generic HTML5 video players
After that, I will share 3 GTM recipes (container templates) for the aforementioned video player tracking
Finally, I will share additional resources/tips related to video tracking in Google Analytics 4 and GTM

We have lots to cover so let’s dive in.

 

 

#1. Built-in video tracking in GA4 (Enhanced Measurement)

When you create a new GA4 property, it automatically has Enhanced Measurement enabled. This is a suite of features that automatically tracks events and sends them to Google Analytics 4. Among things like scroll or site search tracking, it can also track embedded Youtube video players.

You can check whether you have enabled that by going to GA4 Admin > Data Streams (of your particular property) > Click Gear icon.

There you will see whether video tracking is enabled. If it is, you will be able to track the following events:

video_start. Sent when a visitor starts watching a video.
video_progress. When a viewer reaches a particular threshold of the video (10%, 25%, 50%, 75%).
video_complete. When a visitor reaches the end of the video.

Together with those events, a bunch of parameters is tracked too:

video_current_time. The current timestamp of the video where the viewer is at (in seconds)
video_duration. Video duration in seconds.
video_percent. The threshold of the video (without the % sign)
video_provider. The value of this parameter is always “youtube”.
video_title. The title of the video.
video_url. This is the URL of the video.
visible. Returns “1” if the player is visible on the screen while the video engagement was tracked.

If you want to use/see any of these in GA4 reports, you will need to register them as custom definitions.

However, I have noticed various situations where this built-in tracking is just not able to notice the embedded Youtube video player and track respective engagement.

So if you are dealing with a similar situation, read the next chapter + combine that knowledge with this troubleshooting guide. I will now show you how to utilize GTM’s built-in features to track Youtube videos.

 

 

#2. Youtube video tracking with GTM trigger and GA4

If you choose to implement video tracking this way, you should disable Video Engagement tracking features in Enhanced Measurement. Otherwise, you will be at higher risk of occasional duplicate data (when the enhanced measurement is tracking the same things as your GTM setup).

Go to GA4 Admin > Data Streams > Gear Icon > disable Video Engagement tracking. After you did that, let’s continue with the setup.

Also, in this blog post, I presume that you have already installed GA4 in your GTM container. This means that you already have the GA4 configuration tag created.

 

#2.1. Create a Youtube Video Trigger

It all starts with a trigger. In Google Tag Manager, go to Triggers > New > Trigger Configuration and choose Youtube Video. Then enter the following settings:

You can change the Percentage threshold to anything you like, just separate them with a comma. Also, you can enable Pause, Seeking, and Buffering tracking. Personally, I prefer tracking Start, Complete, and Progress (e.g. 25% of the video was watched).

Also, even though the Add JavaScript API support to all Youtube videos is an Advanced setting, I enable it by default because it increases the chance that Youtube video tracking will work.

 

#2.2. Enable built-in video variables

In Google Tag Manager, go to Variables > Configure and enable all video-related variables.

 

#2.3. Create a Google Analytics 4 tag

Now, it’s time to send the Youtube video data to Google Analytics. In GTM, go to Tags > New > GA4 Event Tag and enter the following settings.

Some parts might be confusing so let me explain:

You can enter whatever you want in the Event Name field. I was just trying to follow the same naming convention that is used by the Enhanced Measurement. In my setup, there will be 3 possible event names: video_start, video_progress, and video_complete. This is possible because of the built-in variable called “Video Status”.
All the event parameters that I have included are also optional. If you think that some of them are not valuable, go ahead and remove that. I (once again) decided to follow the naming convention of Enhanced Measurement.

In the triggering section, I select the previously created Youtube video trigger.

 

#2.4 Test the setup

Once you have completed all previous steps, it’s time to test. Enable/Refresh the Preview and Debug mode, refresh the page on your website with the embedded Youtube video player and try to interact with it.

First of all, you should start seeing Youtube Video events in the preview mode. If you don’t see them, read this troubleshooting guide.

Click one of them and check whether your Google Analytics tag has fired.

If yes, then go to Google Analytics 4 DebugView to check if you see the incoming events.

After a while, your events data will appear in Standard Google Analytics reports and Analysis Hub as well. But that might take up to 24 hours. So be patient.

Also, don’t forget to register parameters as video_percent or video_title as custom dimensions (if you want to use them in your GA4 reports).

If the Youtube video trigger is not working, read this guide.

 

#3. How to track Vimeo with Google Analytics 4 and GTM

What if your website does not contain embedded Youtube videos? What if you are using something else? In that case, the built-in Youtube video tracking in Google Tag Manager will not work. You need to find an alternative solution.

 

It all starts with identifying the video player

Before you start with the actual tracking of video player interactions, first you need to identify what kind of video player is that. Video players clearly show their logo in the player box (e.g. Vimeo), others will probably be not that obvious.

If your case is the latter, do the following steps. In your browser, open developer tools (in Chrome, that’s F12 (on Windows)) and then go to Elements tab. Then click this button…

… and then click on the player itself. Now try to browse a bit and locate some clues mentioning the player provider name. For example, in this case, the player that I’m inspecting is JW player.

If you can’t find the name, most likely it is an HTML5 video player.

Once you identify the name of the video player, just google [ video player name ]  tracking with Google Tag Manager and you should find some guide or tutorial. However, there’s a chance that the guide you find will be for Universal Analytics, thus you might need to adapt it to your need.

Let’s imagine, that in our case, we see the “Vimeo” logo at the corner of the embedded video player.

 

#3.1. Create a variable “Is Vimeo player present on a page”

In order to track Vimeo players with GTM on a page, we will need to add a lengthy code to the container. Loading that code on every page is not optimal and will affect the page loading speed, that’s why we should activate that code ONLY when the Vimeo player is actually embedded on that site.

To do that, first, we need to create a Custom JavaScript variable (go to Variables > New > Custom Javascript) and paste the following code:

function () {
for (var e = document.getElementsByTagName(“iframe”), x=0; x < e.length; x++) {
if (/^https?://player.vimeo.com/.test(e[x].src)) {
return true;
}
}
return false;
}

Name this variable cjs – is vimeo player on a page.

If the Vimeo player is embedded in the page, this variable will return true.

Then create a Window Loaded trigger and use that Custom JavaScript variable in it. If the Vimeo player is present, this trigger will be activated. If there is no Vimeo player, that trigger will remain silent.

 

#3.2. Vimeo Auto-Event Listener

Now, it’s Vimeo Listener’s turn. A listener is a function (or a bunch of functions) that are built to keep looking for certain interactions on a page. In this case, the listener will be looking for Vimeo player interactions. If it spots one, it will make that data visible in the Preview and Debug mode.

Create a Custom HTML tag and paste the following code. The original authors of this code are Bill Tripple and Bogdan Bistriceanu from Cardinal Path) but to make it more convenient for GA4, I have modified the code (a bit).

<!–
Google Analytics Tag Manager (V2) custom HTML tag for Vimeo video tracking

Copyright 2016, Cardinal Path, Inc.

Original author: Bill Tripple <[email protected]>
Revised by: Bogdan Bistriceanu <[email protected]>
Updated by: Julius Fedorovicius <[email protected]> and Richard Outram <[email protected]>

Version 2.1
–>
<script>
<!–
Google Analytics Tag Manager (V2) custom HTML tag for Vimeo video tracking

Copyright 2016, Cardinal Path, Inc.

Original author: Bill Tripple
Revised by: Bogdan Bistriceanu
Updated by: Julius Fedorovicius (in 2021) and Richard Outram

Version 2.1
–>
var dataLayer = (typeof(dataLayer) !== “undefined” && dataLayer instanceof Array) ? dataLayer : [];
var videoLabels=[];
var lastP=[];

//we declare variables that will hold information about the video being played
var _playerTitle = {}, _playerAuthor = {}, _playerAuthorURL = {}, _playerUploadDate = {};

try{
init();
}
catch(err){
dataLayer.push({
‘event’: ‘gtm.error’,
‘errorMessage’: e.message,
‘tag’: ‘Vimeo Video Listener’
})
}
function init(){
try{
var player=document.getElementsByTagName(“iframe”);
for (i = 0; i < player.length; ++i) {
var url=player[i].getAttribute(“src”);

if(/player.vimeo.com/video/.test(url)){ // vimeo iframe found
if(!player[i].hasAttribute(“id”)){ // id attribute missing
player[i].setAttribute(“id”,”vimeo_id_”+i); // add id attribute
}
var urlUpdated=false;
if(!/api=/.test(url)){ // check to see if api parameter is in src attribute
url=updateUrl(url,”api”,1);
urlUpdated=true;
}

if(!/player_id=/.test(url)){ // check if player_id is in src attribute
url=updateUrl(url,”player_id”,player[i].getAttribute(“id”));
urlUpdated=true;
}
if(urlUpdated){ // repopulate src attribute with added parameters
player[i].setAttribute(“src”,url)
}
videoLabels[player[i].getAttribute(“id”)]=player[i].getAttribute(“src”); // id to label dictionary
}
}

// Listen for messages from the player
if (window.addEventListener){
window.addEventListener(‘message’, onMessageReceived, false);
}
else {
window.attachEvent(‘onmessage’, onMessageReceived, false);
}
}
catch(err){
}
}

function updateUrl(url,param,value){
try{
return url+((/?/.test(url)) ? “&” : “?”)+param+”=”+value;
}
catch(err){
}
}

// Handle messages received from the player
function onMessageReceived(e) {
try{
var data = e.data;

if(typeof data === “string”){
data = JSON.parse(data);
}

switch (data.event) {
case ‘ready’:
onReady(data);
break;
case ‘play’:
onPlay(data);
break;
case ‘pause’:
onPause(data);
break;
case ‘timeupdate’:
onPlayProgress(data);
break;
}
}
catch(err){
}
}

// Helper function for sending a message to the player
function post(action, value) {
try{
var data = {
method: action
};

if (value) {
data.value = value;
}

var message = JSON.stringify(data);
var player = document.getElementsByTagName(“iframe”);
var url;
var prot;

for (i = 0; i < player.length; ++i) {
url=player[i].getAttribute(“src”);

if(/player.vimeo.com/video/.test(url)){
// Check if protocol exists
prot = player[i].getAttribute(‘src’).split(‘?’)[0].split(‘//’)[0];

// If protocol doesn’t exist, then need to append to “url”
if (!prot){
url=”https:” + player[i].getAttribute(“src”).split(‘?’)[0];
}
player[i].contentWindow.postMessage(data, url);
}
}
}
catch(err){
}
}

function getLabel(id){
try{
return videoLabels[id].split(‘?’)[0].split(‘/’).pop();
}
catch(err){
}
}

//our function that will use the Vimeo oEmbed API to retrieve additional information about the video
function getVimeoInfo(url, callback) {

var script = document.createElement(‘script’);
script.type = ‘text/javascript’;
script.src = url;

document.getElementsByTagName(‘body’)[0].appendChild(script);
}

//the callback function which takes the data received from the Vimeo oEmbed API and places it into the corresponding objectes
function vimeoCallback(e){
//console.log(e);
_playerTitle[e[‘video_id’]] = e[‘title’];
_playerAuthor[e[‘video_id’]] = e[‘author_name’]
_playerAuthorURL[e[‘video_id’]] = e[‘author_url’]
_playerUploadDate[e[‘video_id’]] = e[‘upload_date’]
}

function onReady(data) {
try{
//execute our function which queries the Vimeo oEmbed API once the embedded videos are “ready”
getVimeoInfo(“https://www.vimeo.com/api/oembed.json?url=https://vimeo.com/”+getLabel(data.player_id)+”&callback=vimeoCallback”, vimeoCallback);

post(‘addEventListener’, ‘play’);
post(‘addEventListener’, ‘pause’);
post(‘addEventListener’, ‘finish’);
post(‘addEventListener’, ‘playProgress’);
}
catch(err){
}
}

function onPlay(data){
try{
var t = data.data.duration – data.data.seconds <= 1.5 ? 1 : (Math.floor(data.data.seconds / data.data.duration * 4) / 4).toFixed(2);
dataLayer.push({
event: “video”,
video_action: “play”,
video_url: ‘https://vimeo.com/’ + getLabel(data.player_id),
video_percent: data.data.percent.toFixed(2) * 100,
video_title: _playerTitle[getLabel(data.player_id)].toLowerCase()
});
}
catch(err){
}
}

function onPause(data){
try{
var t = data.data.duration – data.data.seconds <= 1.5 ? 1 : (Math.floor(data.data.seconds / data.data.duration * 4) / 4).toFixed(2);
dataLayer.push({
event: “video”,
video_action: “pause”,
video_url: ‘https://vimeo.com/’ + getLabel(data.player_id),
video_percent: data.data.percent.toFixed(2) * 100,
video_title: _playerTitle[getLabel(data.player_id)].toLowerCase()
});
}
catch(err){
}
}

// Track progress: 25%, 50%, 75%, 100%
function onPlayProgress(data) {
try{
var t = data.data.duration – data.data.seconds <= 1.5 ? 1 : (Math.floor(data.data.seconds / data.data.duration * 4) / 4).toFixed(2); if (!lastP[data.player_id] || t > lastP[data.player_id]) {
lastP[data.player_id]=t;
if (parseFloat(t) != 0){
dataLayer.push({
event: “video”,
video_action: “progress”,
video_url: ‘https://vimeo.com/’ + getLabel(data.player_id),
video_percent: t * 100,
video_title: _playerTitle[getLabel(data.player_id)].toLowerCase()
})
}
}
}
catch(err){
}
}
</script>

Don’t forget to assign the previously created Window Loaded Trigger:

Checkpoint! Let’s see what we’ve created so far:

A Window Loaded Trigger that checks whether Vimeo video player is embedded in the web page (thanks to a Custom JavaScript variable).
A Vimeo Auto-Event Listener (as a Custom HTML tag) fires only when the aforementioned Window Loaded Trigger activates. Every time a Vimeo player interaction occurs, the listener will dispatch a Data Layer event with the following data:
Event Name: video (this value never changes)
video_action (play, pause, or progress)
video_url
video_percent
video_title

As you can see, there is less data (compared to the Youtube trigger) but that’s still pretty useful.

If you want to test this now, enable the Preview and Debug mode, refresh the page with the Vimeo player and try interacting with it. You should start seeing video events in the Preview mode’s left side.

By the way, the Vimeo listener tracks the following video thresholds: 25%, 50%, 75%, 100%. There is no “complete” event here.

 

#3.3. Create Data Layer Variables and a Custom Event Trigger

If you wish to transfer some information from the data layer to other tools (e.g. Google Analytics) with Google Tag Manager, you need to “teach” GTM to fetch it (with the help of Data Layer Variables).

Here’s a screenshot of the video_action variable.

Do the same thing with video_url, video_percent, and video_title.

After variables are configured, it’s time to create a Custom Event Trigger. Vimeo Auto-Event Listener sends all interactions as Data Layer events under the name of “video”.

dataLayer.push({
event: “video”,
…….
});

So the next thing you should do is to create a Custom Event Trigger that listens to ALL video events. Later, it will be assigned to Google Analytics Tag.

In GTM, go to Triggers > New > Custom Event and enter the following settings:

 

#3.4. Create a Google Analytics 4 event Tag

Last but not least, Google Analytics. Now you need to send an event and pass the corresponding data with it. Create a new tag, select GA4 event tag as Tag Type, and enter the following configuration:

The principle here is quite similar to what I did with the Youtube video tracking in the previous chapter.

The event name field’s value will be either video_play, video_pause, or video_progress. That is possible because of the Data Layer variable I inserted in that field.
Since we have video_title, video_url, and video_percent parameters in the data layer (and we have created variables for them), I inserted them in the tag as well.

 

#3.5. Test test test

Don’t forget to test this entire configuration. Enable GTM Preview and Debug mode, go to a page with an embedded Vimeo player and click Play. The next thing you should see is a video event in Preview and Debug mode’s event stream. Click it and see whether the GA4 event tag has fired.

If yes, then go to Google Analytics 4 DebugView to check if you see the incoming events.

After a while, your events data will appear in Standard Google Analytics reports and Analysis Hub as well. But that might take up to 24 hours. So be patient.

Also, don’t forget to register parameters as video_percent or video_title as custom dimensions (if you want to use them in your GA4 reports).

 

#3.6. The entire process in a nutshell

We created a Custom JS variable that returns true if the Vimeo player is embedded on a page.
Then we created a Window Loaded Trigger that checks whether Vimeo video player is embedded in the web page (thanks to a Custom JavaScript variable)
Then we created a Custom HTML tag (a Vimeo Auto-Event Listener). And it will fire on all pages where the Vimeo player is embedded. Important: even if you haven’t interacted with the player yet, that tag will still fire.
Every time a Vimeo player interaction occurs, the listener will dispatch a Data Layer event with the following data:
Event Name: video (this value never changes)
video_action (play, pause, or progress)
video_url
video_percent
video_title

You have created 4 Data Layer Variables and one Custom Event Trigger (for the video event).
Finally, you created a GA4 event tag that fires on the video event and will send the values of those 4 Data Layer Variables to Google Analytics.

 

#4. Tracking HTML5 video player with GA4

As I have already mentioned, different video players require different auto-event listeners if you want to track their engagement. But in general, the principle of the implementation is fairly similar to what we have already done with the Vimeo player.

Create a Custom JavaScript variable that checks if the video player is present on a page.
You add a Custom HTML tag (with the listener code). That listener will be looking for video interactions of a particular type of video player. Fire this tag only if the Custom JavaScript variable returns true (this means that the player is present on a page).
Then that listener will push the video engagement data to the Data Layer.
You will need to create Data Layer variables to access that custom data.
Also, you will need to create a custom event trigger.
Finally, you will need to create a GA4 event tag that fires one that dataLayer.push and you will need to send the video engagement data to GA.

As an example, you can take a look at another popular type of video player, generic HTML5 video. Read this guide to learn more about how to track those players with GA4 and GTM.

 

#5. Three GTM recipes for video tracking with GA4

Those who have been following Analytics Mania for a while know that I have compiled a library of ready-made GTM container templates (called recipes). A solid portion of those recipes also involves video tracking.

However, due to the lack of time (because I have to support many students of my GTM courses), many of those recipes still work only with Universal Analytics.

But I hope that in the future, I will get a chance in my schedule to update all of them to support GA4 as well. One step at a time.

The good news is that while writing this blog post, I have updated 3 recipes to support Google Analytics 4. You can find the links below:

Youtube video tracking
Vimeo video tracking
HTML5 player video tracking

So go ahead, click the links and carefully read the installation/configuration instructions.

 

 

Track Videos with Google Analytics 4 and GTM: Final words

There are many ways how you can track videos with Google Analytics and Google Tag Manager. But those ways/methods depend on what kind of player are you dealing with. Is it a Youtube video player? Vimeo? Something else?

First, you need to investigate the player (and its vendor), and then you need to find the right tracking method for it.

In this blog post, I shared solutions for 3 players (Youtube, Vimeo, HTML5). If you are dealing with some other player, find out the name of that player. Once you do that, do a Google Search and keep looking for something like “[insert video player name] tracking with google tag manager”.

Chances are that you’ll be lucky and find the needed solution.


The post Track Videos with Google Analytics 4 and Google Tag Manager appeared first on Analytics Mania.

Read MoreAnalytics Mania

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments