Guía de seguimiento de video con Google Tag Manager más allá de YouTube

guia de seguimiento de video con google tag manager mas alla de youtube

Actualizado: 29 de marzo de 2025

El simple seguimiento de las visitas a la página no es suficiente para comprender la interacción de los visitantes en tu sitio web. Es crucial capturar otras interacciones, como clics, vistas de elementos específicos y, por supuesto, las interacciones con videos. En la actualidad, YouTube es uno de los reproductores de video integrados más populares, aunque no tengo estadísticas que lo respalden, es una observación común en muchos sitios web. Pero, ¿qué pasa si tu sitio utiliza un reproductor diferente, por ejemplo, Vimeo o un reproductor HTML5 genérico? No te preocupes, porque puedes seguirlos utilizando Google Tag Manager (GTM).

En este artículo, te enseñaré cómo realizar un seguimiento de videos utilizando Google Tag Manager. Abordaré el seguimiento de videos de YouTube, Vimeo y varios otros reproductores. Al final del artículo, compartiré plantillas y recetas listas para usar en GTM que te facilitarán la tarea.

En este artículo aprenderás:

¿Cuál es el plan?

Comenzaremos con el ejemplo más común de seguimiento de videos en Google Tag Manager: el disparador para videos de YouTube. Luego, te mostraré cómo hacerlo con un reproductor de video que GTM no soporta de manera predeterminada, como Vimeo. Finalmente, también te proporcionaré algunas soluciones listas para usar (recetas) diseñadas para varios reproductores de video integrados.

¿Listo? Comencemos.

Capítulo 1. Cómo rastrear videos de YouTube con Google Tag Manager

Si tienes prisa, he creado una receta de seguimiento de videos de YouTube lista para usar. Descárgala, impórtala y configúrala según las instrucciones; comenzará a rastrear videos de YouTube en tu sitio web en un abrir y cerrar de ojos.

Sin embargo, si deseas entender todos los detalles del seguimiento de videos de YouTube, sigue leyendo.

Los pasos para rastrear videos de YouTube con Google Tag Manager son los siguientes:

  1. Crear un disparador para videos de YouTube.
  2. Habilitar las variables de video integradas en GTM.
  3. Crear una etiqueta de evento en Google Analytics 4.
  4. Probar la configuración y publicar.

Veamos cada paso con más detalle.

Paso 1. Crear un disparador para videos de YouTube

Todo comienza con un disparador. En Google Tag Manager, ve a Disparadores > Nuevo > Configuración del Disparador y elige Video de YouTube, luego ingresa la siguiente configuración:

Puedes cambiar el umbral de porcentaje a cualquier valor que desees; solo sepáralos con una coma. Además, puedes habilitar el seguimiento de Pausas, Búsqueda y Buffering. Normalmente, yo rastreo Inicio, Completo y Progreso (por ejemplo, si el usuario vio el 25% del video).

Además, aunque la opción de Agregar soporte de API de JavaScript a todos los videos de YouTube es una configuración avanzada, la habilito por defecto porque aumenta la probabilidad de que el seguimiento de videos de YouTube funcione correctamente.

Paso 2. Habilitar variables integradas para videos de YouTube

En Google Tag Manager, ve a Variables > Configurar y activa todas las variables relacionadas con videos. Esto asegurará que las métricas adecuadas se capturen y se envíen a Google Analytics.

Paso 3. Crear una etiqueta de Google Analytics 4

En este tutorial, asumo que ya has instalado Google Analytics 4 a través de Google Tag Manager (y que tienes una etiqueta de Google Tag). Si no lo has hecho, lee este tutorial primero.

Ahora, es el momento de enviar los datos de video de YouTube a Google Analytics. En Google Tag Manager, ve a Etiquetas > Nuevo > Google Analytics > Google Analytics: Evento GA4 y configura lo siguiente:

Es importante seguir ciertas convenciones de nombres para el seguimiento de videos.

  • Te recomiendo seguir la misma convención de nombres para el seguimiento de videos utilizada en Medición Mejorada. En los pasos anteriores, solo mencioné tres detalles a capturar: el inicio, la finalización del video y el porcentaje de video visto.
  • Todos los parámetros de evento que he incluido son opcionales. Si consideras que alguno de ellos no es valioso, siéntete libre de eliminarlos. Yo, nuevamente, decidí seguir la convención de nombres de la Medición Mejorada.

En la sección de activación, selecciono el disparador para videos de YouTube que creamos anteriormente.

Paso 4. Probar la configuración

Una vez que hayas completado todos los pasos anteriores, es hora de probar. Activa el modo de Vista Previa y Depuración y navega hasta la sección de la página donde se encuentra el reproductor de video.

Deberías empezar a ver eventos de video de YouTube en el modo de vista previa. Si no los ves, lee esta guía de solución de problemas.

Haz clic en uno de los eventos y verifica si tu etiqueta de Google Analytics se ha activado.

Si es así, confirma esto navegando a DebugView de Google Analytics 4 para comprobar si los eventos se han registrado allí.

Nota: Si deseas usar estos detalles en tus informes de GA4, no olvides registrar parámetros como video_percent o video_title como dimensiones personalizadas, ya que, por alguna razón, aún no están disponibles por defecto.

Capítulo 2. Cómo rastrear el reproductor de Vimeo con Google Tag Manager (solución personalizada)

Podrías pensar: “El seguimiento de YouTube parece sencillo, pero tengo un reproductor de video diferente en mi sitio. ¿Qué funcionará en mi caso?” El seguimiento de video de YouTube integrado en Google Tag Manager no funcionará. En su lugar, necesitas encontrar una solución personalizada.

Todo comienza identificando el reproductor de video

Antes de preocuparte por el seguimiento real, primero debes identificar qué tipo de reproductor de video es. Mientras que esto puede ser evidente para la mayoría de los reproductores de video, puede no serlo con algunos.

Si este es tu caso, abre las herramientas de desarrollador en tu navegador (en Chrome, es F12 en Windows) y ve a la pestaña Elementos. Haz clic en este botón y luego haz clic en el reproductor. Intenta buscar pistas que mencionen el nombre del proveedor del reproductor. Por ejemplo, en este caso, el reproductor que estoy inspeccionando es el JW Player.

Si no puedes encontrar el nombre, probablemente sea un reproductor de video HTML5.

Una vez que identifiques el nombre del reproductor de video, simplemente busca en Google [nombre del reproductor de video] seguimiento con Google Tag Manager y deberías encontrar alguna guía o tutorial.

Imaginemos que, en nuestro caso, vemos el logotipo de “Vimeo” en la esquina del reproductor de video integrado.

Paso 1. Crear una variable “¿Está presente el reproductor de Vimeo en la página?”

Necesitaremos agregar un código extenso al contenedor para rastrear reproductores de Vimeo con Google Tag Manager en una página. Cargar ese código en todas las páginas no es óptimo y afectará la velocidad de carga de la página, por lo que debemos activar ese código SÓLO en aquellas páginas donde el reproductor de Vimeo esté embebido.

Para hacerlo, primero necesitamos crear una variable de JavaScript personalizada y pegar el siguiente código:

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;
}

Si la página tiene un reproductor de Vimeo embebido, esta variable devolverá verdadero.

A continuación, crea un disparador de Vista de Página y utiliza esa variable de JavaScript personalizada en él. Si el reproductor de Vimeo está presente, este disparador se activará. Si no hay un reproductor de Vimeo, el disparador permanecerá inactivo.

Verifica esto en el modo de Vista Previa y Depuración, y deberías obtener algo como esto.

Paso 2. Crear un listener de eventos automáticos para Vimeo

Ahora es el turno del Listener de Vimeo. Un listener es una función (o un conjunto de funciones) diseñada para seguir buscando ciertas interacciones en una página. En este caso, el listener estará buscando interacciones del reproductor de Vimeo. Si detecta alguna, hará que esos datos sean visibles en el modo de Vista Previa y Depuración.

Crea una etiqueta HTML personalizada y pega el siguiente código. El código original fue creado por Bounteous, pero lo he modificado un poco para hacerlo más conveniente para GA4.

<script type="text/javascript" id="gtm-vimeo-tracking">

;(function(document, window, config) {
    'use strict';
    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]
    }
});
</script>

No olvides asignar el disparador de Carga de Ventana que creaste anteriormente.

¡Punto de control! Veamos lo que hemos creado hasta ahora:

  • Comenzamos creando un disparador de Vista de Página que verifica si hay un reproductor de Vimeo embebido en la página (gracias a una variable de JavaScript personalizada).
  • Un Listener de Eventos Automáticos de Vimeo (como una etiqueta HTML personalizada) se activa cuando el disparador mencionado anteriormente se activa. Cada vez que se produce una interacción en el reproductor de Vimeo, el listener enviará un evento a la Capa de Datos con la siguiente información:
    • Nombre del Evento: video (este valor nunca cambia)
    • acción_video (play, progress o complete)
    • porcentaje_video
    • título_video
    • proveedor_video
  • Si deseas probar esto ahora, activa el modo de Vista Previa y Depuración, navega hasta el reproductor de Vimeo embebido e intenta interactuar con él. Deberías comenzar a ver eventos de video en el lado izquierdo del modo de Vista Previa.

Paso 3. Crear variables de capa de datos y un disparador de eventos personalizados

Google Tag Manager no reconoce los eventos de la Capa de Datos (como disparadores) ni otros datos (como variables) de manera predeterminada. Así que, si deseas transferir información a otras herramientas (por ejemplo, Google Analytics), necesitas “enseñar” a GTM a obtener cierta información (con la ayuda de las Variables de Capa de Datos).

Después de configurarlas, es hora de crear un Disparador de Evento Personalizado. El Listener de Eventos Automáticos de Vimeo envía todas las interacciones como eventos de Capa de Datos bajo “video”.

dataLayer.push({
event: "video",
  ...
});

Así que lo siguiente que debes hacer es crear un Disparador de Evento Personalizado que escuche TODOS los eventos de video. Más tarde, lo asignaremos a la Etiqueta de Google Analytics 4.

En GTM, ve a Disparadores > Nuevo > Evento Personalizado e ingresa la siguiente configuración:

Paso 4. Crear una etiqueta de GA4 para Vimeo

Por último, pero no menos importante, está Google Analytics. Ahora necesitas enviar un evento y pasar los datos correspondientes. Crea una nueva etiqueta, selecciona Google Analytics > Google Analytics: Evento GA4 como tipo de etiqueta, e ingresa las tres variables de Capa de Datos.

Cada vez que se genere un evento de video, los servidores de Google recibirán un Evento GA4, con datos reales que reemplazarán dinámicamente los valores predeterminados en todas las tres variables. El nombre del evento resaltará el estado del video.

Paso 5. Probar, probar y probar

Como con todas las implementaciones de Google Tag Manager, necesitamos probarlo. Activa el modo de Vista Previa y Depuración de GTM, ve a una página con un reproductor de Vimeo embebido y haz clic en Reproducir. Si está configurado correctamente, esto activará un evento de video en la corriente de eventos de modo de Vista Previa y Depuración. Haz clic en él y verifica si se ha activado la etiqueta de GA4.

Además, no olvides consultar los informes de DebugView de Google Analytics. Puedes acceder a ellos navegando a Administrador > DebugView.

El proceso completo, en resumen

  • Creaste una variable de JS personalizada que devuelve true si la página tiene un reproductor de Vimeo embebido.
  • Luego, creaste un disparador de Vista de Página que se activa cuando detecta el reproductor de video de Vimeo en la página (gracias a la variable de JavaScript personalizada).
  • Después, creaste una etiqueta HTML personalizada (un Listener de Eventos Automáticos de Vimeo). Esta se activará en todas las páginas donde el reproductor de Vimeo esté embebido. Importante: incluso si no has interactuado aún con el reproductor, esa etiqueta se activará.
  • Cada vez que se produzca una interacción en el reproductor de Vimeo, el listener enviará un evento a la Capa de Datos con los siguientes datos:
    • Nombre del Evento: video (este valor nunca cambia)
    • acción_video (play, progress o complete)
    • porcentaje_video (solo funciona con eventos de progress)
    • título_video
  • Has creado Variables de Capa de Datos y un Disparador de Evento Personalizado (para el evento de video).
  • Finalmente, creaste una etiqueta de Google Analytics 4 que se activa en el evento de video y enviará los valores de esas 3 Variables de Capa de Datos a Google Analytics.

Capítulo 3. Seis recetas de seguimiento de videos de GTM

Créelo o no, pero el flujo que he descrito en la sección de seguimiento del reproductor de Vimeo se aplica a muchos otros reproductores de video que no son de YouTube:

Dado que la mayoría de las recetas de GTM son creadas por autores distintos, su convención de nombres también es diversa. Así que las unifiqué un poco.

Utilizarán la convención de nombres de GA4 (por ejemplo, parámetros como video_title, video_provider). Todas las recetas enviarán eventos de video_progress y video_complete. Algunas recetas enviarán video_play (mientras que otras usarán video_start). Esto se debe a que algunas recetas envían video_play cada vez que un visitante presiona reproducir en el mismo video (aun cuando presionó pausa unos segundos antes). Para evitar eventos duplicados de video_start, a veces opté por video_play.

Quizás en el futuro encuentre más tiempo para solucionar esto.

Siéntete libre de descargar cualquiera de estas recetas de Google Tag Manager y comienza a rastrear reproductores de video en poco tiempo. ¿No te dije que el seguimiento de videos con Google Tag Manager era bastante fácil?

He notado que la receta de HTML5 no funciona bien con otras (bueno, al menos algunas de ellas). A veces se apodera de todas las interacciones, y otros listeners de video dejan de funcionar. Así que asegúrate de que el listener de eventos automáticos de HTML5 no se active en la misma página que el JW player, etc.

Todo lo demás debería estar bien. Si notas algún error, házmelo saber.

Video tracking con Google Tag Manager: Palabras finales

Cuando se trata de seguimiento de videos con Google Tag Manager, lo primero que viene a la mente es el seguimiento de videos incrustados de YouTube.

No te culpo, ya que esta es la plataforma de alojamiento de videos más popular del mundo.

Sin embargo, si estás tratando con un reproductor de video que no es de YouTube, eso sigue siendo posible con algunas soluciones personalizadas.

En este artículo, he explicado cómo puedes rastrear videos de YouTube y videos no de YouTube incrustados en tu sitio.

Para ahorrarte tiempo, también he incluido un montón de recetas que puedes descargar, importar, configurar y comenzar a rastrear videos en cuestión de minutos. Solo descarga cualquiera de ellas, impórtala a tu cuenta de GTM y comienza a rastrear videos en un abrir y cerrar de ojos.

Todas estas soluciones de seguimiento de videos con Google Tag Manager siguen el mismo principio, así que una vez que domines una, dominarás todas.