Tracking iframe interactions using GTM

In some cases, you might embed 3rd party snippets on your website, for example, social media embedded timelines, loan calculators on your e-commerce shop, some partner advertising snippets, etc.

As you might probably know – it’s not possible to track any clicks Within an iframe using GTM’s traditional click tracking approach, but in this short article, I will show you a method of how you can keep track of how often people interacted anywhere within the iframe to estimate how often those blocks are used.

In this example, we will use Google Analytics to store those events, but you can easily adjust the setup for other vendors as well.

In case you prefer a video format, you can watch it below. You can also subscribe to my YouTube channel!

1. Create Custom HTML tag

We will use this Javascript template to detect when a visitor focuses an iframe, so you can copy-paste it under the new custom HTML tag and I will explain what are we doing here in a moment:

<script>
  (function(){
    focus(); // Set focus on the window
    var iframeSelector = "iframe";
    var gaEventName = "iframe_click";
    // DO NOT EDIT ANYTHING BELOW unless you feel confident
    var iframeListener = window.addEventListener('blur', function() {
      if (document.activeElement === document.querySelector(iframeSelector)) {
        dataLayer.push({
            "event": "GAEvent", // used for GA event trigger
            "event_name": gaEventName // used as event name in GA4
        });
      }
      window.removeEventListener('blur', iframeListener);
    });
  })();
</script>

So your tag would look similar to what I have here:

Don’t save it yet, as we will adjust a few things to work for your specific scenario.

First of all, at the top, we have a function that focuses on our current window. As we determine if the iframe is selected by using focus event this resets focus to the main window in case it’s modified at some point before our script loads.

focus(); // Set focus on the window

Next, we have a variable where we define CSS selector for our Iframe. It’s important to adjust it in case you have multiple iframes on the page, otherwise, your data will include clicks on all of those iframes.

var iframeSelector = "iframe";

If you are not sure how to get a CSS selector for your iframe you can check my article on GTM DOM elements to get some sense of how to do this.
Any changes you do here should be included in double quotes, otherwise, your script won’t work.

For example, if I have an iframe that I want to track with an ID “snippet_iframe”

Then my variable with CSS selector will look like this:

var iframeSelector = "iframe#snippet_iframe";

Alright, the next variable that we have is the Google Analytics event name, and it will be used and sent to GA4 and will be visible in your reports.
You can adjust this name to whatever you see fit for your event naming convention and that follows these requirements from Google. It’s fine to leave it the same as I have it in my template:

var gaEventName = "iframe_click";

Then we have a bunch of code that you should not edit unless you feel confident with JavaScript.
First, we are creating an event listener when our main window is blurred (when we focus on iframe, for example).

var iframeListener = window.addEventListener('blur', function() {

Then, we check if currently focused element is our iframe (based on CSS selector that we have provided):

if (document.activeElement === document.querySelector(iframeSelector)) {

And if the active element matches our iframe, we are sending a dataLayer push with our event name:

dataLayer.push({
  "event": "GAEvent", // used for GA event trigger
  "event_name": gaEventName // used as event name in GA4
});

As you might have guessed, we will use the dataLayer event “GAEvent” as a trigger to send data back to Google Analytics.
If you feel confident, you can also modify “GAEvent” to whatever value that fits you best or add additional dataLayer variables to collect additional information.

So, for the triggers, you can either fire this tag on all pages (not recommended unless your iframe is on all or majority of the pages), or you can target only pages with an iframe.

In case you want to track iframe interactions on all pages, the complete tag setup would look very similar to this:

2. Add Custom event trigger

Now, after we have saved the JavaScript template, let’s create a custom event trigger that will notify GA tag about the iframe click.

Go to the “Triggers” section and create a new one.

From Trigger Type select “Custom Event” and the event name will be the same as you have in JavaScript template – “GAEvent”. In case you are using a different value then you need to specify it here.

You can now save the trigger, and let’s do the final step – Create the GA event tag.

3. Create Google Analytics event tag

Finally, let’s send an event to Google Analytics. Create a new tag under “Tags” section and select tag type “GA4 Event”.

From the “Configuration Tag” field select your GA4 settings variable (In my case it’s called “GA4 – Base tag”).

For “Event Name” we will use a dynamic value that we are passing from our custom script (“event_name” field). To do that we will fetch dataLayer contents, by clicking plus icon and creating a new variable.

From variable configuration select “Data Layer Variable” and the variable name will be “event_name”.
You can save the variable and now it should be automatically applied to your Google Analytics tag.

Now, all you need to do is to select a trigger for “GAEvent” that we have created previously for our custom event, and your tag should look very similar to this:

And that’s it! Now you can save your tag, test your events and collect your iframe interactions.

I hope you will find this template useful, and let me know if you’ll have any questions.
Cheers

13 thoughts on “Tracking iframe interactions using GTM

  1. Is there a specific way to set this up but instead of sending the data to GA$, sending it directly to google ads? or to do both I suppose?

    1. Yes, this is just a regular dataLayer event. You can rename it to something more specific to iframe like “iframeFocus” and use the same trigger to fire a Google Ads conversion tag, FB pixel, GA4 event, etc.

  2. I have a problem. I host html5 games in an iframe on my site. Google Analytics 4 doesn’t track those anymore correctly so my avg interaction time is very low on those pages, compared to games that don’t run in an iframe. Can you think of a way to stop that behavior. I came to this place in hope that I could trigger those clicks on the iframe in a smart way to show google the interaction and have comparable values for games in an iframe and non-iframed games.

  3. Hi, thank you very much for this blog. This custom HTML works with my website but the GAEvent is pushed in the datalayer when I first interact with the iframe. Is it possible to adapt this cHTML with a specific click class from a button? Thank your for your help!

  4. Hi! I am looking for a similar solution for an e-commerce iFrame – meaning the e-commerce parameters (item value, item name etc.) need to be sent to the parent frame along with the event. How will the script look in this situation?

    Really appreciate your effort and help. Thank you in advance!

    1. Hi Anca,

      Any information from a 3rd party iframe is not accessible unless you have direct source access there (to add GTM/dataLayer).
      You can check if your iframe source or class names or other attributes contain any dynamic information that you could use in the event (check the comments above on how to extract “src” from the iframe object).
      If it doesn’t contain anything useful then you would need to try other options involving developers (e.g. adding GTM in the 3rd party iframe source for example).

  5. Worked! Also had to change the single quotes to quotation marks for the datalayer to not cause an error in GTM. A weird glitch that happens on all sites on which I use a form of your code is that a part of the debug notification that always shows on the bottom right of the screen that is being debugged somehow overlays every instance of iframes anywhere on the page, but it only occurs when in GTM Preview debug mode. Thanks again! Completed code that implements the iframe source url, that is working(!):

    focus(); // Set focus on the window
    var iframeSelector = “iframe#sa_player”;
    var gaEventName = “sa_player_click”;
    // DO NOT EDIT ANYTHING BELOW unless you feel confident
    var iframeListener = window.addEventListener(‘blur’, function() {
    if (document.activeElement === document.querySelector(iframeSelector)) {
    var src = document.querySelector(iframeSelector).getAttribute(‘src’);
    dataLayer.push({
    “event”: “GAEvent”,
    “event_name”: gaEventName,
    “iframeSource”: src
    });
    }
    window.removeEventListener(‘blur’, iframeListener);
    });

  6. I’m not familiar with JS, so I’m stuck, and I need to ask for help a little further. I created the DLV for iframeSource, and added it under event parameters for the event tag. However, the tag fails to fire after modifying the custom HTML code as follows:

    focus(); // Set focus on the window
    var iframeSelector = “iframe#sa_player”;
    var gaEventName = “sa_player_click”;
    // DO NOT EDIT ANYTHING BELOW unless you feel confident
    var iframeListener = window.addEventListener(‘blur’, function() {
    if (document.activeElement === document.querySelector(iframeSelector)) {
    var src = iframeSelector.getAttribute(‘src’);
    dataLayer.push({ ‘event’: ‘GAEvent’, ‘event_name’: gaEventName, ‘iframeSource’: src });
    }
    window.removeEventListener(‘blur’, iframeListener);
    });

    Thanks for your help!

    1. Hey,

      sorry, my mistake.
      Try replacing the “var src” part with this:
      var src = document.querySelector(iframeSelector).getAttribute('src');
      instead of this
      var src = iframeSelector.getAttribute('src');

      Since we should search for “src” attribute in the DOM element, not in the CSS selector string.
      Let me know if that works!

  7. I have found this method very useful, and I’m using this for multiple sites. Could you add to the article the event parameters of the GA4 tag that can be tracked in GA as Custom Definitions? Also, even more importantly for me, could you add to the article how to track the Source URL of the iframe (“src=…”)? Thanks again for this article!

    1. Hi Jade,
      When you have detected that currently active element is your iframe (just above dataLayer push), you can try to extract SRC attribute just by queryng iframe element like this:
      var src = iframeSelector.getAttribute('src');

      And then pass it as an additional parameter in dataLayer, e.g.:
      dataLayer.push({ 'event': 'GAEvent', 'event_name': gaEventName, 'iframeSource': src });

      And then as usual just create a DLV variable in GTM and pass it as a custom dimension to GA4.

      Hope that helps!

Leave a Reply

Your email address will not be published. Required fields are marked *