Cardinal Path’s response to COVID-19 Cardinal Path is sharing all we know to help marketers during COVID-19.  Learn more.
February 11th, 2015 update
November 15th, 2014 update
  • track onunload event
  • minor fix to error reporting
June 20th, 2014 update
  • now supports multiple players on the same page
  • includes optional code to add the necessary enablejsapi=1 to the video URL
  • now track the video title instead of the video id
September 16th, 2015 update

During our GTM+UA webinar I was asked about tracking YouTube videos with the help of Google Tag Manager and Universal Analytics. I quickly demonstrated how we’re doing it in our WASP playground.

Here’s a step by step guide to the macros, tags and rules required to track YouTube video embeds on your website.

A note for Google Analytics users: For sake of demonstration I’m showing Universal Analytics, but you could easily replace the Universal Analytics Event by a regular Google Analytics one and everything will work fine.

Prerequisites

We will use the YouTube JavaScript API to expose user interactions with the video. In order for this to work, each of your YouTube embeds will need to include “enablejsapi=1” to the link of the video, for example:

<iframe width="420" height="315" src="//www.youtube.com/embed/Rvw0uxuYBCo?enablejsapi=1" frameborder="0" allowfullscreen></iframe>

Note: the “Is Youtube present” macro could be modified to automatically add the enablejsapi if it’s not there, but this will result in a quick flash of the Youtube frame.

Note: by default, related videos will be shown and tracked. If you want to disable this, add “&rel=0” to the Youtube embed link.

What you’ll get

Under Behavior/Events/Top Events, you will see an event category named “video”, with event actions named “pause”, “play”, 0%, 25%, 50%, 75% and 100%. The event label will be the unique identifier of the video.

Custom Report for Video Performance

If you want to get details about how individual videos are performing, follow those steps:

  1. Go in yout Behavior/Events/Top Events/video report;
  2. Click on “Customize” in the top left of the report;
  3. Under Dimension Drilldown, remove the “Event Category” dimension and switch “Event Action” with “Event Label”, so it now reads Event Label/Event Action;
  4. Modify the filter so it now reads “Event Category equals video”, so only videos are shown in this new custom report;
  5. Voilà! You now have detailed performance info about each individual video embedded on your website.

Macros

Is Youtube present?

You have two options here, either use this macro to automatically detect when a video is embedded on a page, or use a rule to include the Youtube Listener tag only on pages where you know there’s a video.

Macro Name: Youtube is present
Macro Type: Custom JavaScript
Custom JavaScript:
// Return "true" if there is at least one Youtube video on the page
function () {
    for (var e = document.getElementsByTagName('iframe'), x = e.length; x--;)
        if (/youtube.com\/embed/.test(e[x].src)) return true;
    return false;
}

event

Macro Name: event
Macro Type: Custom Event

dataLayer action

Macro Name: dataLayer action
Macro Type: Data Layer Variable
Data Layer Variable Name: action

dataLayer label

Macro Name: dataLayer label
Macro Type: Data Layer Variable
Data Layer Variable Name: label

Tags

Listen for Youtube activity

Tag Name: Youtube Listener
Tag Type: Custom HTML Tag
Firing Rule: Youtube present
HTML:
<script type="text/javascript">
// OPTIONAL: Enable JSAPI if it's not already on the URL
// note: this will cause the Youtube player to "flash" on the page when reloading to enable the JS API
for (var e = document.getElementsByTagName("iframe"), x = e.length; x--;)
  if (/youtube.com\/embed/.test(e[x].src))
     if(e[x].src.indexOf('enablejsapi=') === -1)
        e[x].src += (e[x].src.indexOf('?') ===-1 ? '?':'&') + 'enablejsapi=1';

var gtmYTListeners = []; // support multiple players on the same page
// attach our YT listener once the API is loaded
function onYouTubeIframeAPIReady() {
    for (var e = document.getElementsByTagName("iframe"), x = e.length; x--;) {
        if (/youtube.com\/embed/.test(e[x].src)) {
            gtmYTListeners.push(new YT.Player(e[x], {
                events: {
                    onStateChange: onPlayerStateChange,
                    onError: onPlayerError
                }
            }));
            YT.gtmLastAction = "p";
        }
    }
}

// listen for play/pause, other states such as rewind and end could also be added
// also report % played every second
function onPlayerStateChange(e) {
    e["data"] == YT.PlayerState.PLAYING && setTimeout(onPlayerPercent, 1000, e["target"]);
    var video_data = e.target["getVideoData"](),
        label = video_data.video_id+':'+video_data.title;
    if (e["data"] == YT.PlayerState.PLAYING && YT.gtmLastAction == "p") {
        dataLayer.push({
            event: "youtube",
            action: "play",
            label: label
        });
        YT.gtmLastAction = "";
    }
    if (e["data"] == YT.PlayerState.PAUSED) {
        dataLayer.push({
            event: "youtube",
            action: "pause",
            label: label
        });
        YT.gtmLastAction = "p";
    }
}

// catch all to report errors through the GTM data layer
// once the error is exposed to GTM, it can be tracked in UA as an event!
// refer to https://developers.google.com/youtube/js_api_reference#Events onError
function onPlayerError(e) {
    dataLayer.push({
        event: "error",
        action: "GTM",
        label: "youtube:" + e
    })
}

// report the % played if it matches 0%, 25%, 50%, 75% or completed
function onPlayerPercent(e) {
    if (e["getPlayerState"]() == YT.PlayerState.PLAYING) {
        var t = e["getDuration"]() - e["getCurrentTime"]() <= 1.5 ? 1 : (Math.floor(e["getCurrentTime"]() / e["getDuration"]() * 4) / 4).toFixed(2);         if (!e["lastP"] || t > e["lastP"]) {
            var video_data = e["getVideoData"](),
                label = video_data.video_id+':'+video_data.title;
            e["lastP"] = t;
            dataLayer.push({
                event: "youtube",
                action: t * 100 + "%",
                label: label
            })
        }
        e["lastP"] != 1 && setTimeout(onPlayerPercent, 1000, e);
    }
}


// Crossbrowser onbeforeunload hack/proxy
// https://developer.mozilla.org/en-US/docs/WindowEventHandlers.onbeforeunload
window.onbeforeunload = function (e) {
 var e = e || window.event;
 // For IE and Firefox prior to version 4
 if(e)
 e.returnValue = 'na';
 // For Safari
 return 'na';
};
window.onbeforeunload = trackYTUnload;
 
function trackYTUnload() {
 for (var i = 0; i < gtmYTplayers.length; i++)
 if (gtmYTlisteners[i].getPlayerState() === 1) { // playing
 var video_data = gtmYTlisteners[i]['getVideoData'](),
 label = video_data.video_id+':'+video_data.title;
 dataLayer.push({
 event: 'youtube',
 action: 'exit',
 label: label
 });
 }
}
// load the Youtube JS api and get going
var j = document.createElement("script"),
    f = document.getElementsByTagName("script")[0];
j.src = "//www.youtube.com/iframe_api";
j.async = true;
f.parentNode.insertBefore(j, f);
</script>

UA Youtube event

If you are using Google Analytics instead of Universal Analytics, simply change the Tag Type to Google Analytics and everything will work fine.

Tag Name: Youtube Event
Tag Type: Universal Analytics
Tracking ID: UA-XXXXXX-Y
Track Type: Event
Event Tracking Parameters:
Category: {{event}}
Action: {{dataLayer action}}
Label: {{dataLayer label}}
Firing rule: Youtube event

Rules

Youtube embed found on a page

Rule Name: Youtube present
Conditions: {{event}} equals gtm.dom AND {{youtube is present}} equals true

Youtube is telling us something

Rule Name: Youtube event
Conditions: {{event}} equals youtube

Putting it all together

That’s it! Now you can track Youtube video embeds on your own website thanks to Google Tag Manager and Universal Analytics.

Don’t forget to use Google Tag Manager “debug & preview” with WASP to make sure everything works fine before you publish.

This topic, and many more, are covered in our GTM+UA  Master Class. Please check the Cardinal Path training calendar for more locations.

Check out the new, and up to date version by Nicky Yuen.

Hungry for more? Check out our Analytics Rising Virtual Conference on October 11. Sign up today!

Sharing is caring!

Popular

COVID-19 Crisis Navigator​

In partnership with Dentsu, Cardinal Path helps you distill the overwhelming news and information into a bi-weekly report highlighting emerging trends and insights during the pandemic.

EXPLORE THE REPORT

Message Sent

Thank you for registering.

Message Sent

Thank you for registering.

Message Sent

Success!
Your message was received.

Thank you.

Message Sent

Thank you.

Message Sent

Thank you

Message Sent

Thank you.

Message Sent

Thank you

Message Sent

Thank you

Message Sent

Thank you.

Message Sent

Thank you.

Message Sent

Thank you for registering.

Message Sent

Thank you.

Click here to download access the tool.

Message Sent

Thank you for registering.

Message Sent

Thank you for registering.

Message Sent

Thank you for registering.

Message Sent

Thank you for registering.

Message Sent

Thank you for registering.

Message Sent

Thank you for registering.

2020 Online Behavior Live Dashboard

Message Sent

Thank you for registering.

Thank you for your submission.

Message Sent

Thank you for registering.

Message Sent

Thank you for registering.

Message Sent

Thank you for registering.

Message Sent

Thank you for registering.

Message Sent

Thank you for your submission.

Message Sent

Thank you for registering.

Message Sent

Thank you for registering.

Thank you for registering.

Cardinal Path is continuing with its series of free training. Next we are conducting training on Google Data Studio. Check it out here.
Cardinal Path hosted a live session to connect with you and answer all your questions on Google Analytics.
Get all the expertise and none of the consultancy fees in this not-to-be-missed, rapid-fire virtual event.

Thank you for submitting the form.

Thank you for submitting the form.

Message Sent

Thank you for registering.

Message Sent

Thank you for registering.

Message Sent

Success! Thank you
for reaching out.