Tracking Complex Interactions in Iframes On The Same Domain – Google Analytics & Iframes, Pt 2



Welcome to part two of our series on tracking user behavior within iframes. In Part One, we discussed how to track simple user interactions within cross-domain iframes by using the postMessage API. In Part Two, we’ll be discussing what to do when you’re tracking more complicated user interactions, where greater insight is required.


For this to work, you need to be able to add unadulterated code on the iframe and the page the iframe is inserted on. If you’ve got a third-party service you’d like to track, and you can’t insert code snippets on their pages, this will not work and you’re out of luck. If you can’t add code to the iframe, you can’t measure interactions with it, period. Do not pass GO, do not collect $200. Sorry.

The Challenge

When tracking complicated interactions within an iframe on your site, there’s really only one challenge that we need to solve: our user must have the same Client ID for every hit they send to Google Analytics, be it from within the iframe or from the page containing it.

Remember, the Client ID is a unique, random value that Google Analytics stores in the _ga cookie and is particular to the site you’re currently on. The default Client ID consists of a random, unsigned 32-bit integer and a timestamp rounded to the nearest second; here’s yours:

Just kidding, you don’t have JavaScript enabled (or you’ve blocked us from setting the _ga cookie)!

No matter what your approach, you must ensure the Client ID is the same for the hits being sent from your parent frame and the hits being sent from your iframe. Remember, your iframe is basically a new tab the user has opened up. It doesn’t have access to the context it is being loaded in, just like the parent doesn’t have access to the iframes context (yes, this is an oversimplification, for the technically proficient clamoring to disagree in the audience).

If you send hits with two different client IDs, you’ll wind up with two different sessions (gasp!), and worse, two entirely different, irreconcilable users (oh no!) within Google Analytics.

Three Potential Situations

There are three potential situations that typically arise when trying to track complicated user interactions within iframes:

  1. On a Subdomain or Same Domain As The Page Holding Them
  2. On Another Domain and Added to the Page with JavaScript
  3. On Another Domain Interactions In An Iframe and Embedded on the Server

Today we’ll cover #1, tracking interactions in an iframe that lives on the same domain or a subdomain of the parent frame, e.g. your iframe is on and your site is on

Getting Started

For this particular scenario, the solution is simple; you’ll need to configure your Google Analytics tracker (or Tags in Google Tag Manager) to set your cookieDomain to auto. Then, simply insert the Google Analytics Tracking Snippet or Google Tag Manager snippet (only one, not both!) in the code for the content of the iframe.

For Google Tag Manager users, this is a setting under the More Settings menu, beneath our Hit Type. You’ll configure a Field to Set and set it to ‘auto’.

Setting cookieDomain to auto instructs Google Analytics to share the same Client ID across all subdomains on your site. With this configuration in place, you can safely fire hits from within your iframe, no sweat. However, don’t forget the iframe is it’s own ‘page’, just as though your user has opened a new tab. The iframe has its own gtm.js event in Google Tag Manager and will fire a pageview if you’re using the standard GA snippet.

This means the user’s session will have at least two pageviews when they load the page, one for the parent and one for the iframe. Technically, that would make this session not a bounce. In some cases, this is your expected behavior.

If this is not what you’d like, consider using a separate container or modifying your snippet and not firing a pageview, unless you want to count the iframe loading as such.

With that configuration in place, you’re all set! Add Google Analytics tracking to your hearts content; your user will be tracked using the same Client ID, and therefore data they send will be associated with the same session and user. Don’t forget, this only works if your iframe and your parent frame are on the same domain.

Still having iframe issues? Let us know in the comments, or look for future parts in our poorly-named two-part series.

Dan Wilkerson is a former LunaMetrician and contributor to our blog.

  • Javier Matos

    Hi, thank you for sharing your tips about GA and iframes.

    I have an issue with a page whose iframe is in a subdomain (they both use ‘auto’ for cookie domain and use the same ClientID, but the parent page and the iframe have different TrackingID because the data is saved in different GA properties). The problem I have is that it was working fine, but since I migrated from Google Analytics (old _gaq tracking code) to the new Universal Analytics (new ga tracking code), now it seems sessions are not kept. I mean, the number of sessions have increased a lot (and also the bounce rate), like if users had started a new session, even when they are not.

    Did you face a case like that? Which advice could be given to help in finding my issue?

    Thank you again!

    • Dan Wilkerson

      Hi Javier,

      Are you using GTM in the iframe or the parent page? Typically, when bounce rate === 100%, that indicates the _ga cookie is being reset on every pageview. I’d take a go with the Debug setting turned on and review the output in the console when the ‘create’ statement is run.


      • Javier Matos

        Hi Dan, thank you for your help.

        The _ga cookie is not being reset. I use classic GA code, but not the Tag Manager for it. The main page and the iframe use the same _ga cookie (they share it because the iframe is in a subdomain using the same domain as the parent page). They are sending data to different TrackingIDs, because we want to use a different GA property for the iframe. I suspect that maybe using the same cookie but with different TrackingIDs could be the problem… Maybe _ga cookie is related to a specific TrackingID in Google servers…

        • Dan Wilkerson

          Oh, I can assure you that the Tracking ID / GA cookie combination you’ve described is totally valid; the _ga cookie contains the client ID, which is how Google Analytics identifies a user as unique in a property. There is no intrinsic link between a client ID and a Tracking ID.

          Is the suspicious data only in your property for the main site?

          • Javier Matos

            The GA property for the main site has correct values (they are the same as before). The iframe is the one with suspicious data: before moving from _gaq to ga there where about 2.43 sessions per user. Now there are 11.27 sessions per user. If I find how to fix it I will share it here.

            Thank you again! 🙂

          • Dan Wilkerson

            Sure thing. Good luck! Happy to answer any other ?’s that come up.


    • Javier Matos

      I have solved it!

      Hello again Dan, I came to share the problem I had and the solution that worked for me. Moving from ga.js to analytics.js was not the only thing I did.

      My previous setup with ga.js had the following sequence of hits, which worked fine:
      1. main page tracking object creation (with _setAccount)
      2. main page pageview hit (with _trackPageview)
      3. iframe tracking object creation (with _setAccount)
      4. iframe pageview hit (with _trackPageview)

      When I migrated to analytics.js, I wanted to include a dimension with the pageview hit. That dimension was filled with an asynchronous value that was computed with a javascript function. Because of that, the pageview hit of the main page was sent the last, so the hit sequence that was causing the issue was as follows:
      1. main page tracking object creation (with ga(‘create’, …))
      2. iframe tracking object creation (with ga(‘create’, …))
      3. iframe pageview hit (with ga(‘send’, ‘pageview’))
      4. main page pageview hit (with ga(‘send’, ‘pageview’, ))

      What I did to solve the issue was to send the pageview hit just after the tracking object creation without waiting for any other thing, so I came back to the first sequence listed. Then, for sending the dimension, I set it’s value once I know it, and let any following hit to send it’s data to Google Analytics. In my case, the dimension was to know if the user was anonymous or authenticated, and that’s why I had to wait…

      I hope this helps for anyone with a problem like mine.


      • Dan Wilkerson

        Hi Javier,

        Yeah, that will fix your problem. It wouldn’t hurt to send an Event once that data came back from your async service, just to make sure it makes it into Google Analytics!


  • markghobril

    Dan, I am working with a company in which I am creating ads and they are put in a traffic exchange as a text ad with a link. The Traffic Exchange uses a script similar to…. My domain in the text ad will be much different obviously then what the traffic exchange is hosted on. I have no result at all in GA coming from the site listed in the text ad. Is there any solution to this?

  • sachfm

    Hey Dan, could you explain how this might get simplified if your iframe is also hosted on your domain, just on a different, “hidden” URL?

  • Roman K

    Hi Dan. Do you know of a way to prevent an extra pageview in the following situation:
    * We have Page A at Landing on it fires a pageview. All good.
    * On this page, there is a modal popup with an iframe that hosts content from Page B on A pageview for is recorded, which is good.
    * As the popup closes, we register another pageview for the parent Page A, which is not good.
    How can this last pageview be prevented?
    Thank you.

Contact Us.

Follow Us



We'll get back to you
in ONE business day.
Our Locations
THE FOUNDRY [map] LunaMetrics

24 S. 18th Street
Suite 100

Pittsburgh, PA 15203


4115 N. Ravenswood
Suite 101
Chicago, IL 60613


2100 Manchester Rd.
Building C, Suite 1750
Wheaton, IL 60187