Friday, September 24, 2021
No menu items!
HomeData Analytics and VisualizationTrack Vimeo Player with Google Tag Manager and Google Analytics 4

Track Vimeo Player with Google Tag Manager and Google Analytics 4

Google Tag Manager offers a built-in Youtube video trigger. But that’s about it. If you are dealing with some other player, you will need to implement custom solutions.

And that’s exactly what we are going to do in this blog post. I will show you how to track Vimeo player with Google Tag Manager and Google Analytics 4.

 

Video tutorial

I have also created an extensive video tutorial where I explain various video tracking techniques (Youtube, Vimeo, etc.). So if you prefer video content, take a look at the tutorial below.

 

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

In order to track Vimeo player 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.

 

#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). Also, there were some other minor updates that were made over the years.

<!–
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. 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:

 

#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 one of my other blog posts.

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.

 

#5. Let’s 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).

 

GTM recipe for Vimeo tracking

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 portion of those recipes also involves video tracking.

As you have probably guessed, Vimeo video tracking is among them. Go to this page, download the needed files, and carefully read the installation/configuration instructions.

 

Track Vimeo Player with Google Tag Manager and GA4: Final words

Since Vimeo player tracking is not automatically supported by Google Tag Manager, we had to implement a custom solution that involves JavaScript code in a Custom HTML tag. Here’s what the entire process looked like:

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

Then we created 4 Data Layer Variables and one Custom Event Trigger (for the video event).
Finally, we 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.

 

The post Track Vimeo Player with Google Tag Manager and Google Analytics 4 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