Create a variable “Is Vimeo player present on a page”
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;}
If the page has a Vimeo player embedded in it, this variable will return true.
Custom Javascript - Vimeo player is present
Then create a Pageview 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.
Check it in Preview and Debug mode, and you should get something like this.
Vimeo Auto-Event Listener
<script type="text/javascript" id="gtm-vimeo-tracking">
;(function(document, window, config) {
'use strict';
// The API won't work on LT IE9, so we bail if we detect those UAs
if (navigator.userAgent.match(/MSIE [678]\./gi)) return;
config = cleanConfig(config);
var handle = getHandler(config.syntax);
if (document.readyState !== 'loading') {
init();
} else {
document.addEventListener('DOMContentLoaded', function() {
init();
document.addEventListener('load', init, true);
});
}
function init() {
var videos = filter_(selectAllTags_('iframe'), isVimeo);
if (!videos.length) return;
loadApi(function() {
forEach_(videos, listenTo);
});
}
function isVimeo(el) {
return el.src.indexOf('player.vimeo.com/video/') > -1;
}
function loadApi(callback) {
if (isUndefined_(window.Vimeo)) {
loadScript('https://player.vimeo.com/api/player.js', callback);
} else {
callback();
}
}
function listenTo(el) {
if (el.__vimeoTracked) return;
el.__vimeoTracked = true;
var video = new Vimeo.Player(el);
var percentages = config._track.percentages;
var eventNameDict = {
'play': 'play',
'pause': 'pause',
'complete': 'ended'
};
var cache = {};
video.getVideoTitle()
.then(function(title) {
forEach_(['play', 'pause', 'complete'], function(key) {
if (config.events[key]) {
video.on(eventNameDict[key], function() {
handle(key, title);
});
}
});
if (percentages) {
video.on('timeupdate', function(evt) {
var percentage = evt.percent;
var key;
for (key in percentages) {
if (percentage >= percentages[key] && !cache[key]) {
cache[key] = true;
handle(key, title);
}
}
});
}
});
}
function cleanConfig(config) {
config = extend_({}, {
events: {
'play': true,
'pause': true,
'complete': true
},
percentages: {
each: [],
every: []
}
}, config);
forEach_(['each', 'every'], function(setting) {
var vals = config.percentages[setting];
if (!isArray_(vals)) vals = [vals];
if (vals) config.percentages[setting] = map_(vals, Number);
});
var points = [].concat(config.percentages.each);
if (config.percentages.every) {
forEach_(config.percentages.every, function(val) {
var n = 100 / val;
var every = [];
var i;
for (i = 1; i < n; i++) every.push(val * i);
points = points.concat(filter_(every, function(val) {
return val > 0.0 && val < 100.0;
}));
});
}
var percentages = reduce_(points, function(prev, curr) {
prev[curr + '%'] = curr / 100.0;
return prev;
}, {});
config._track = {
percentages: percentages
};
return config;
}
function getHandler(syntax) {
syntax = syntax || {};
var gtmGlobal = syntax.name || 'dataLayer';
var uaGlobal = syntax.name || window.GoogleAnalyticsObject || 'ga';
var clGlobal = '_gaq';
var dataLayer;
var handlers = {
'gtm': function(state, title) {
if (state.indexOf('%') === -1 && state.indexOf('play') === -1) {
dataLayer.push({
event: 'video',
video_provider: 'vimeo',
video_action: state,
video_title: title.toLowerCase(),
video_percent: undefined
});
} else if (state === '0%'){
dataLayer.push({
event: 'video',
video_provider: 'vimeo',
video_action: 'start',
video_title: title.toLowerCase(),
video_percent: undefined
});
} else if (state.indexOf('play') === -1) {
dataLayer.push({
event: 'video',
video_provider: 'vimeo',
video_action: 'progress',
video_percent: state,
video_title: title.toLowerCase()
});
}
},
'cl': function(state, title) {
window[clGlobal].push(['_trackEvent', 'Videos', state, title]);
},
'ua': function(state, title) {
window[uaGlobal]('send', 'event', 'Videos', state, title);
}
};
switch(syntax.type) {
case 'gtm':
dataLayer = window[gtmGlobal] = window[gtmGlobal] || [];
break;
case 'ua':
window[uaGlobal] = window[uaGlobal] || function() {
(window[uaGlobal].q = window[uaGlobal].q || []).push(arguments);
};
window[uaGlobal].l = +new Date();
break;
case 'cl':
window[clGlobal] = window[clGlobal] || [];
break;
default:
if (!isUndefined_(window[gtmGlobal])) {
syntax.type = 'gtm';
dataLayer = window[gtmGlobal] = window[gtmGlobal] || [];
} else if (uaGlobal&& !isUndefined_(window[uaGlobal])) {
syntax.type = 'ua';
} else if (!isUndefined_(window[clGlobal]) && !isUndefined_(window[clGlobal].push)) {
syntax.type = 'cl';
}
break;
}
return handlers[syntax.type];
}
function extend_() {
var args = [].slice.call(arguments);
var dst = args.shift();
var src;
var key;
var i;
for (i = 0; i < args.length; i++) {
src = args[i];
for (key in src) {
dst[key] = src[key];
}
}
return dst;
}
function isArray_(o) {
if (Array.isArray_) return Array.isArray_(o);
return Object.prototype.toString.call(o) === '[object Array]';
}
function forEach_(arr, fn) {
if (Array.prototype.forEach_) return arr.forEach.call(arr, fn);
var i;
for (i = 0; i < arr.length; i++) {
fn.call(window, arr[i], i, arr);
}
}
function map_(arr, fn) {
if (Array.prototype.map_) return arr.map.call(arr, fn);
var newArr = [];
forEach_(arr, function(el, ind, arr) {
newArr.push(fn.call(window, el, ind, arr));
});
return newArr;
}
function filter_(arr, fn) {
if (Array.prototype.filter) return arr.filter.call(arr, fn);
var newArr = [];
forEach_(arr, function(el, ind, arr) {
if (fn.call(window, el, ind, arr)) newArr.push(el);
});
return newArr;
}
function reduce_(arr, fn, init) {
if (Array.prototype.reduce) return arr.reduce.call(arr, fn, init);
var result = init;
var el;
var i;
for (i = 0; i < arr.length; i++) {
el = arr[i];
result = fn.call(window, result, el, arr, i);
}
return result;
}
function isUndefined_(thing) {
return typeof thing === 'undefined';
}
function selectAllTags_(tags) {
if (!isArray_(tags)) tags = [tags];
return [].slice.call(document.querySelectorAll(tags.join()));
}
function loadScript(src, callback) {
var f, s;
f = document.getElementsByTagName('script')[0];
s = document.createElement('script');
s.onload = callCallback;
s.src = src;
s.async = true;
f.parentNode.insertBefore(s, f);
function callCallback() {
if (callback) {
callback();
s.onload = null;
}
}
}
})(document, window, {
'events': {
'play': true,
'pause': false,
'complete': true
},
'percentages': {
'every': 25,
'each': [0, 90]
}
});
/*
* v1.0.1
* Created by the Google Analytics consultants at http://www.lunametrics.com
* Written by @notdanwilkerson
* Documentation: https://github.com/lunametrics/vimeo-google-analytics/
* Licensed under the MIT License
* Modified by Julius Fedorovicius at https://www.analyticsmania.com
*/
</script>Don’t forget to assign the previously created Window Loaded Trigger:
Create Data Layer Variables and a Custom Event Trigger
dataLayer.push({
event: "video",
...
});GTM, go to Triggers > New > Custom Event and enter the following settings:
Create a Google Analytics 4 Tag
video_percentvideo_titlevideo_provider




