I'll start out by saying, that you may need the latest version of VideoJS for this to work. And I assume you have basic understanding of Google Tag Manager and Google Analytics. Also because you are reading this, you are familiar with VideoJS already. If you don't care about how to, and are only looking for a quick installation. Feel free to download the JSON file, to import VideoJS tracking directly in your Google Tag Manager installation.
Please note that you will need to adjust the Variable Google Analytics - UA ID to match your Google Analytics ID.
For a more hands-on approach, open your Google Tag Manager, and let’s get to work. As a side note, the names are roughly translated from German. So if any name is not 100% corresponding to the name in Google Tag Manager, I blame Google Translate.
First we need to define our variables that we can use in our triggers later on. We are going to create a Google Analytics variable, this is the most common and if you have on already, feel free to skip this. Since we are using Event Tracking to track our VideoJS interactions we’ll need to define a variable for Action, Category and Label. And lastly, we want a variable to track VideoJS instances on a page. So 5 in total.
Let’s open up the Variables tab;
If you have a Google Analytics variable, feel free to skip this. But make sure to use change your variable when we need to implement this in our Triggers.
- Create a new User Defined Variable.
- Give the variable a name, we chose Google Analytics - UA ID
- Select the variable type Google Analytics-Settings
- In the tracking ID, add your Google Analytics ID
- Open up the More settings dropdown, and in Fields to be defined, under Field name add anonymizeIp, and under Value add true.
- Save
The last part is required to comply with the General Data Protection Regulation (GDPR) law in Europe.
- Create a new User Defined Variable.
- Give the variable a name, we chose vjs – eventAction
- For the variable type, select data layer variable
- Data layer variable name: eventAction
- Save
Repeat step 1.2;
- Variable name: vjs – eventCategory
- Data layer variable name: eventCategory
Repeat step 1.2;
- Variable name: vjs – eventLabel
- Data layer variable name: eventLabel
- Create a new User Defined Variable.
- Give the variable a name, we chose Javascript – VideoJS
- For the variable type, select Javascript-Variable
- The name of the global variable is going to be videojs
- Save
Now that we have our 5 variables defined, let’s look at the triggers we’re going to be using.
For our implementation we want to have 2 triggers, one trigger checks if there is a VideoJS module embedded on the webpage. The second trigger checks if there is an interaction with a VideoJS module.
- Create a new trigger, I called mine Pageview - VideoJS Player is Present
- As Trigger-Type, select Window Loaded
- Select the radio button Some events that are triggered when loading a window
- Select the Javascript – VideoJS variable, in the second dropdown select, does not equal, and write undefined in the third input.
So we can now check: If VideoJS is not undefined, do something.
- Create a new trigger, I called this one Custom - VideoJS Interaction
- As Tag-Type, select Custom Event
- Event name is Video, also check Use match with regular expression
- Create a new Tag, I called this one cHTML - VideoJS Listener
- For the Tag-Type we want to use Custom HTML
Copy and paste the following JavaScript, feel free to adjust the percentages for which you want to trigger an event. In this snippet we are firing events at 5, 10, 15, 20, 25, 50, 75 and 100 percentage of video playtime.
<script>
(function(dataLayer){
var i = 0;
// Array of percentages at which progress notifications are pushed to the dataLayer
var markers = [5,10,15,20,25,50,75,100]; //adjust these values if you want different progress reports
var playersMarkers = [];
function findObjectIndexById(haystack, key, needle) {
for (var i = 0; i < haystack.length; i++) {
if (haystack[i][key] == needle) {
return i;
}
}
return null;
}
function eventToDataLayer (thisObject, eventType, currentTime) {
var eventName;
if (thisObject.id_) {
eventName = thisObject.id_;
} else {
eventName = 'not set';
}
dataLayer.push({
event: "Video",
eventCategory: "VideoJS",
eventAction: eventType,
eventLabel: eventName,
videoCurrentTime: currentTime
});
}
// Loop through all Players on the page
for (var video in window.videojs.players) {
var player = window.videojs.players[video];
//Pushes an object of player.id and progress markers to the array playersMarkers
playersMarkers.push({
'id': player.id_,
'markers': []
});
player.on('play', function(e){
var playResume = 'Resumed video';
if (parseInt(this.currentTime()) < 2) {
playResume = 'Played video';
}
eventToDataLayer (this, playResume, this.currentTime());
});
player.on('pause', function(e){
eventToDataLayer (this, 'Paused video', 'Paused video');
});
player.on('ended', function(e){
eventToDataLayer (this, '100%', this.currentTime());
});
player.on('seeking', function(e){
eventToDataLayer (this, 'Timeline Jump', this.currentTime());
});
player.on('timeupdate', function(e){
var percentPlayed = Math.floor(this.currentTime()*100/this.duration());
var playerMarkerIndex = findObjectIndexById(playersMarkers,'id',this.id_);
if(markers.indexOf(percentPlayed)>-1 && playersMarkers[playerMarkerIndex].markers.indexOf(percentPlayed)==-1)
{
playersMarkers[playerMarkerIndex].markers.push(percentPlayed);
console.log(percentPlayed);
eventToDataLayer (this, percentPlayed + '%', this.currentTime());
}
});
player.on('error', function(e){
eventToDataLayer (this, 'Video error', e.message);
});
}
})(window.dataLayer = window.dataLayer || []);
</script>
- For Trigger select Pageview – VideoJS Player is Present
- Save
- Create a new Tag, I called this one GA - Event - VideoJS Interaction
- As Tag-Type, select Google Analytics – Universal Analytics
- Tracking Type: Event
- Category: {{vjs – eventCategory}}
- Action: {{vjs – eventAction}}
- Label: {{vjs – eventLabel}}
- Google Analytics-Settings {{Google Analytics – UA ID}}
- And as Trigger select Custom – VideoJS Interaction
- Save
And that’s it! Publish your Google Tag Manager container and try it out. You should see the events happening in real time in your Google Analytics console.