How to Track Facebook iFrames with Google Analytics

When Facebook launched Facebook iFrame Tabs for Pages, tracking visitor interactions, goals or whatever inside the iFrame in for example Google Analytics suddenly seemed very easy. A common answer in forums when people asked about this was "just add your regular Google Analytics code to your iFrame page".

Facebook Logo

Unfortunately things aren't that easy. If you just add your regular Google Analytics script to your iFrame page, you are missing 2 important things:

  1. Tracking traffic sources to your Facebook iFrame Tab is not possible
    • Facebook will be the referral for all the traffic to your Facebook iFrame Tab
  2. Visitors using Internet Explorer will not be tracked

In this blog post I show you how these problems can be overcomed.

Handling the Traffic Source Problem

In an earlier blog post LunaMetrics explained how tracking Traffic Sources to the Facebook iFrame Tab Page could be done (I recommend you read the article from LunaMetrics since they also explains some other important things). The method is to send the visitor to a page outside Facebook that will track the traffic source, and then redirect the visitor to the Facebook iFrame Tab Page.

However, if you just redirect the visitor, Google Analytics will probably not track the visit since the Google Analytics script will not be able to load before the redirect occurs. In other words, you must use a delayed redirect.

The delay can either be "wait 1 second, hope Google Analytics has loaded, and then redirect". Or as I do in this script, check if Google Analytics probably has loaded, and then redirect (or frame the page as I do).

Since I'm framing the page, I don't have to create an additional redirect page. Everything is handled by the script in the Facebook iFrame Page.

As an example, I have created a Facebook iFrame Tab Page at this adress:


If I want to track the traffic source to that page, I will link to my iFrame Page and not to the Facebook iFrame Tab Page.

My Facebook iFrame Page can be found at this adress:

If you would track campaign traffic to the Facebook iFrame Page (ex. promote your Facebook Page in a newsletter), then you should add campaign tracking to the URL like this:

In regards of campaign tagging, I really recommend my own Google Analytics Campaign URL Tool. :)

Google Analytics tracking code for Facebook iFrame Tab Pages

Below is the Google Analytics code I'm using to track Facebook iFrame Pages. The code handles:

  • Campaign tracking
  • Delayed redirect if the visitor is landed on the iFrame Page
    • The code is checking if _gaq.push is loaded before it redirect the user to the Facebook iFrame Tab

Change values in red, and add the code between <head> and </head> to your iframe page.

Remove formatting from Code

  1. <script type="text/javascript">
  2. // This script is provided AS IS without warranty of any kind.
  3. // See for more information.
  4. // Smacked together by Eivind Savio May 2011

  5. var FacebookURL = '';
  7. var _gaq = _gaq || [];
  8. _gaq.push(['_setAccount', 'UA-XXXXXX-X']);
  9. _gaq.push(['_addIgnoredRef', '']);

  10. // If Google Analytics is loaded and this page isn't framed inside our Facebook URL, frame the page.
  11. if (_gaq.push && self.location == top.location) {
  12. // Create a fake URL that we can filter in Google Analytics. This pageview also sends the traffic source data to Google Analytics.
  13. _gaq.push(['_trackPageview','/facebook/campaign-tracking/']);
  14. // Tracking done, let's frame the page
  15. setTimeout(top.location.href = FacebookURL, 200);
  16. } else if (self.location == top.location) {
  17. // If Google Analytics doesn't load within 2 seconds, refresh and frame the page anyway. People dislike waiting. Change the time if you like.
  18. setTimeout(top.location.href = FacebookURL, 2000);
  19. } else {
  20. // The Page is Framed. Let's track it.
  21. _gaq.push(['_trackPageview']);
  22. _gaq.push(['_trackPageLoadTime']);
  23. }
  25. (function() {
  26. var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
  27. ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '';
  28. var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  29. })();
  30. </script>

Why Internet Explorer Privacy Settings can make your life miserable

To be able to make things work in Internet Explorer can be a nightmare, whether it is CSS, javascript or in this case - tracking Facebook iFrame Tab Pages in Google Analytics.

Internet Explorer - Cookies blocked from iFrame

The problem isn't related to Google Analytics, you will get the same problem with other web analytic tools. The problem is related to Internet Explorer and handling of cookies from a third party website inside an iFrame.

If the users Privacy Settings in Internet Explorer is set to "Medium" or higher, Internet Explorer will block cookies from your iFrame Page and Google Analytics, and the visit will not be recorded.

The solution: P3P (Platform for Privacy Preferences)

To get around this problem you will have to send a P3P (Platform for Privacy Preferences) Header in your iFrame Page.

A P3P Header may look something like this:


What you add as a CP value doesn't really matter. CP="Eivind is Cool" will also work. So where do the quoted CP values come from?

I had a really hard time before I was able to get P3P work in Internet Explorer. On my way to a working solution I came across the P3P Policy Editor from IBM. This editor has generated the values for my P3P Header based on the information I added to my P3P XML file.

I have generated 2 files:

  • P3P reference file:
    • The reference file should always be located at the adress /w3c/p3p.xml
  • Full P3P policy:

Just to be specific, creating and uploading P3P XML files isn't necessary, but if you want to show your Internet Explorer visitors your Privacy Preferences upload these files.

Internet Explorer - P3P XML File missing

Image: P3P XML File missing.

Internet Explorer - P3P XML File Reference

Image: P3P XML File Reference in place.

Below you find code examples of how to send a P3P Header in ASP.NET, ASP and PHP.

P3P Header for ASP.NET using global.asax

ASP.NET implementation may look like the following:

Remove formatting from Code

  1. protected void Application_BeginRequest(Object sender, EventArgs e)
  2. {
  3. //
  4. HttpContext.Current.Response.AddHeader("p3p", "CP=\"IE is often a NIGHTMARE\"");
  5. }

P3P Header for "old" ASP

ASP implementation may look like the following (implement this as the first code in your .asp iFrame page):

Remove formatting from Code

  1. <% Response.AddHeader "P3P","CP=""IE is often a NIGHTMARE"""%>

P3P Header for PHP

PHP implementation may look like the following (implement this as the first code in your .php iFrame page):

Remove formatting from Code

  1. <?php
  2. header('P3P: CP="IE is often a NIGHTMARE"');
  3. ?>

P3P Header for PHP using .htaccess

PHP implementation may look like the following (source):

Remove formatting from Code

  1. <IfModule mod_headers.c>
  2. Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IE is often a NIGHTMARE\""
  4. Header set P3P "policyref=\"/w3c/p3p.xml\""
  5. </IfModule>

Source: Manipulating HTTP Headers with htaccess

The easiest method to identify if your P3P Header is sent, and if Google Analytics is tracking the visit in Internet Explorer, is to install ieHTTPHeaders.

If you see anything that could be improved or errors (I'm not a programmer), or if you just found this article valuable, feel free to comment.

Happy tracking your Facebook iFrame Page.

Related articles

Du kan følge kommentarer til denne posten med RSS. Du må ha javascript aktivert for å kunne kommentere. Tilbaketråkk er deaktivert.

Tags : , , ,

  • Comments are closed
Has added some changes to the script that detects if Google Analytics has loaded.

Before I was checking if _utm.gif was loaded, now I check if _gaq.push is loaded instead.

If you are using the script, feedback is welcomed.
  • Axel
  • 6/8/2011 10:05:00 PM
Great post Eivind. I'm not able to Google 1. Dunno why.

However, i have a question.
I see that you check that gaq.push has loaded. That does not mean utm.gif has loaded, because its asynchronous. When we do a gaq.push trackPageview, we dont know when we ll receive the utm.gif.

It could be a problem at this place:

// Tracking done, let's frame the page
top.location.href = FacebookURL;

You're changing the page, just after calling a trackPageview. I think the utm.gif wont be received before changing page.
I have this kind of problem whenever I call a trackPageview in a onclick tag. The onclick tag executes the GA code but it does not prevent the next page loading. The only solution I know is to explicitly change the page in 200ms with a setTimeout and adding a return false; to prevent the <a> tag to work normally.
Hi Axel

First, thanks for your feedback.

In my my first version I was checking if _utm.gif had loaded, and did some controlled tests with that solution. Not just only me testing, but I also sent a test link to my colleagues. What I found was that using _utm.gif failed with too many Safari/Mac users (they were often recorded as direct traffic). Checking gaq.push has given much more reliable results.

Another reason for switching to gaq.push was that I have also been experimenting with BTBuckets on the Facebook iFrame, and with that combination the _utm.gif solution failed too often. I tested with adding setTimeout up to 3 second before framing the page without any good results. Using gaq.push seems to be a much better combination with BTBuckets.

I have however seen your advice elsewhere for onclick events. Adding this small delay is probably smart thing to do. I will update the code.

Again, thanks for your feedback Alex. If you use the code, I would appreciate feedback about any issue you comes across.
Hi there

I don't quite understand the bit, "Create a fake URL that we can filter in Google Analytics. This pageview also sends the traffic source data to Google Analytics."

Do I need to add a custom filter to my domain in Google Analytics?? If so, how? If not, please could you explain this further?

Hi Jon

Great question.

The only purpose of the "fake URL" is to track traffic sources to our Facebook iFrame Tab. The "fake URL code" will only be executed when the iFrame content is loaded outside Facebook. Going to will execute the "fake URL code", going directly to will not execute the code.

With other words, pageviews reported in Google Analytics will be inflated because of the "fake URL".

To avoid this you can add a exclude filter to your Google Analytics Facebook Profile. Using a predefined filter your filter will look something like this:
  • Exclude - Traffic to the subdirectores - That are equal to
  • Subdirectory: /facebook/campaign-tracking/
The "fake URL" will then be excluded from your reports, but the traffic source will still be maintained since that info was saved into a cookie with the execution of the "fake URL" pageview.

It can also be wise to create 2 Google Analytics Profiles. One using the filter and one unfiltered profile. Your unfiltered profile will be your "backup" just in case your filter isn't working as expected.

Hope this helps.
  • Mike
  • 6/28/2011 8:04:00 AM
This seems to be working great - thanks so much for posting for everyone to use.

One question I have though is that I cannot get a goal to fire in Google Analytics.

I modified the code to do a PHP redirect to a new page if the visitor already "likes" the page so I could track the landing page/fan gate, and the liked page separately. Anyone else had success with goals using this method?
Hi Mike

Glad you liked it.

Regarding your goal problem. Haven't tried your solution. How are your goal funnel setup? Something like this?

/facebook/campaign-tracking/ -> /facebook/already-fan/


/facebook/campaign-tracking/ -> /facebook/new-fan/

As long as Google Analytics are given enough time to "fire" the pageview before the redirect, it shouldn't be a problem (if I haven't misunderstood something about what you are trying to do).
Hi Elvind

Thanks again for this post!

Sorry to be a bit slow but I don't understand where to put the code for the P3P

I have a index.php file for the app i created for my facebook iframe tab

Do I paste the php code option in there??
  • Grant
  • 6/30/2011 9:11:04 PM

Sorry one more basic question...

I have two pages for my iframe because I use a reveal method for my iframe app

I have a page people land on if they haven't liked the facebook page and then a page that's revealed when they do like the page

Which page do i paste the code into?

Or do I paste it into both??
Hi Grant

I have a index.php file for the app i created for my facebook iframe tab.
Do I paste the php code option in there??

Yes, you paste the P3P code in that file. The P3P code should probably be the first code in that page since I have seen people write that if not, the P3P code would not always work (I haven't had any problem with that, but better to be safe than sorry).

Regarding where to paste the code. Just paste the code into both pages, that is easiest and "safest".

If you don't paste the code into both pages you must still tweak the regular Google Analytics script by adding
_gaq.push(['_addIgnoredRef', '']);
If not Facebook will be registered as the traffic source.
  • Grant
  • 7/1/2011 9:05:32 AM
Thanks so much Eivind

That's totally clear now...
  • Grant
  • 7/1/2011 9:11:03 AM
Hi Eivind

I just wanted to ask you about the 'analytics filter'

Never used these before.

Can you give me a brief instruction on what to do here and why?

  • Grant
  • 7/1/2011 9:19:16 AM
Oh dear! I feel really stupid asking this!!

But after I went back to my app I just wondered if I just past your code in Eivind, or i paste your code into the 'head' tag as well as my google analytics code.

Could you put me straight?

  • Billy
  • 7/29/2011 2:03:19 AM
Hello Eivind,

Thanks very much for this post. I added a P3P header in php at the top of my page, and it's working. Google Analytics began tracking visits from IE on my iFrame page.

But the tracking seems to be hit or miss. Sometimes it records a visit, sometimes not. Even when I know someone has clicked on my Facebook page tab via IE, GA does not register the visit.

Any suggestions on how to ensure that GA tracks visits consistently? Thank you.
Hi Billy

Glad the post helped you a little bit.

Even when I know someone has clicked on my Facebook page tab via IE, GA does not register the visit.

Difficult to say why this happens. First, I assume your P3P code is the first code on your page?

I have also seen people write that not allowing caching may help. I'm not a PHP coder, but something like this should do the trick:

header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past

If no-caching helps, I would appreciate your feedback on that.

  • Billy
  • 8/1/2011 6:44:33 PM
Hi Elvind,

Adding the script to disallow caching did not help. I'll give it another day and test again.

Yes, the P3P header is the first code on the page, before the DOCTYPE line. So now the first two pieces of code are the P3P header followed by the no-cache code, and then the DOCTYPE line.

I didn't create the P3P xml files, just added the header.

The page isn't redirected before being iframed on facebook, as the lack of referrer info isn't a concern for me at this point.


  • Billy
  • 8/5/2011 2:32:34 AM
Well, looks like it's been working the past few days. No problems to report. Thanks, Eivind!

PS - Apologies for misspelling your name in the previous post.
Good to hear Billy.

Regarding misspelling, I'm quite used to that. Not so often in writing, but people from US sometimes call me Elvind when we are talking for some reason.
You put the P3P meta tag before the doctype declaration? That shouldn't validate and may cause some browsers to go into some sort of different rendering mode...

I put the meta tag inside head with the other meta tags, I'm currently trying to get Google Analytics to track inside an iFrame and of course I ran into this iFrame/P3P issue.
I'm not using the P3P Meta tag, I'm using P3P HTTP Headers.

It's no point in using the P3P Meta tag, it doesn't work.

  • Ann K
  • 8/12/2011 5:06:09 PM

I have tried to use this script in my iframe page but maybe I am doing some thing wrong.

I have put the above script in my page. I have also followed the instructions on your other blog posts about tracking likes and comments. I left this to test over night and form what i can see in the analytics it hasn't worked.

One question though -Do I need the regular Google analytics code as well? or should I leave that out?

Can you take a look at my code and see if I am doing something wrong.

Thank you.
Hi Eivind

VERY nice article describing a very complicated problem. Thanks for that.

Can you elaborate a little about what the status is today using your solution. Is your code 100% bullet proof or are there still some issues solving the P3P problem. Is it as good as it gets - and how good is that?

Kind regards,

Hi Chrilles

I don't guarantee that my code is 100 % bullet proof, but I don't think there should be any issues with my solution either.

The last controlled tests I did across browsers and OS showed good results. All browsers & traffic sources were tracked correctly in that test. But for you to be 100 % sure how good the solution is, you will have to test it yourself.

You can also use Google Analytics easily on your Facebook Welcome tab by using We built it on WordPress as a hosting platform for Facebook Pages custom content and each site is a subdomain of Pholiofy. You just have to set up your Google Analytics for the subdomain and then post the web id into a field in the dashboard.
  • Vlad
  • 11/9/2011 5:46:53 PM
Hello, Eivind,
Thanks for the great post!
I'm a bit new in all this coding stuff so maybe you could help me.
This tracking code for Facebook iFrame Tab Pages you share assumes that app itself is located on the same domain, as your main site(as lunametrics assumes)?
Suppose I have my site on and my app is somewhere on Shouldn't I be using Cross-Domain Tracking? Or inserting your code with my UA-XXXXX is enough?

Thanks in advance!
Hi Vlad

The answer to that is it depends on what level you want to track the traffic to your iFrame.

If you just want to track traffic sources to the iFrame, you don't need Cross Domain tracking.
However, if you want to know ex. what traffic sources your website got, and which of those sources sent traffic to your iFrame, then you would have to use Cross Domain tracking.

If the iFrame is on the same domain as your website, you will get that information anyway since the iFrame and your site is sharing cookies.
  • Brian
  • 1/26/2012 2:50:27 PM
Hi Eivind,

Nice article! This is a problem that many of us have, and it is great to get help with finding a solution Bredt smil

One question that I have is, if we link to an external site to the redirect page to the Facebook app, will we lose all the social context in the adverts available to us?

Also will we lose metrics such as "connections" that we see in Facebook?

We have tried custom variables to track performing adverts, to ascertain source of likes and other actions. However we have had issues with inconsistent data.

Thanks for this article!

Hi Brian

Not sure if I fully understand your questions. Could you please elaborate?

Hi Elvind

I have the p3p up and running, and it is doing it's magic, I am getting IE trafic in analytics. BUT I am still seeing a lot, lot more clicks in facebooks ads, than I am seeing visit in analytics. Have you heard about this before, and what is your take on that?

This is the page -

Thanks for any help or advice you might offer

Mads Gorm
Hi Mads

Clicks and visits would never be the same (and that goes for other advertising as well). The best thing to do is to compare trends.

If I click on an ad now, and a click on the same ad again before my session expires, that would be counted as 2 clicks & 1 visit.
But, the result can also be opposit if I look at a longer time frame.
If I click on your ad today, and tomorrow I visit your page again directly (direct traffic), it would be counted as 1 click & 2 visits from your ad.

Did it answer your question?

Hi Eivind

Thanks for taking the time to answer -

The difference is at lot bigger than between adwords clicks, and analytics visits. I am seeing less than half visits compared to the number of clicks, and I have not observed anywhere near that difference with adwords. How much of a difference do you see? How much would you consider acceptable?

I suspect the problem could be that ads are placed behind the chat function, so at lot of people click on the ads by mistake - and leave to quickly for the cookie to load?

Mads Gorm
  • Izzy
  • 2/3/2012 4:45:25 AM
Great article and thanks for taking your time to write this guide. I have a couple of question.

(1) Do I need to tag outbound links from my parent domain to my page that is iframed in Facebook? As per normal cross domain tracking?

(2) I'm getting double pageviews per 1 visit which isn't correct. I assume this is the redirect then the code on the page loading a second time?

Hi Izzy

(1) Is your framed page on another domain, or on your own domain? The answer also depends on what kind of data you want. Let's assume your framed page is on another domain, and the user first visits your domain.
  1. If you want to know what the original traffic source was to your domain, then you would have to do cross domain tracking.
  2. If you don't care about the original traffic source to your domain, then you would use campaign tracking.
If the framed page is on the same domain (as my framed page is), then I don't have to do anything to get the original traffic source since the GA cookie "lives" on the same domain.

(2) Have you implemented a filter that excludes the "fake" URL?

  • Eric
  • 2/15/2012 2:19:53 AM
I built an fb app (iframe was my only option since FBML is no longer allowed) that I was going to promote with a facebook ad campaign. My problem is that I can't get metrics on this (paid) traffic at all.
In particular, i need to see the referrer or have some other way to distinguish between the sources i am paying for.

I like your solution of track and redirect -- it avoids all the facebook iframe issues -- but Facebook Ad Campaign rules say the ad can't land on a redirect. If i want to run facebook-to-facebook this project doesn't seem possible.
Other people MUST have run into this. Can anyone describe how they solved it? Or am I missing something??
thanks in advance,
Hi Eric

I don't do much Facebook Advertising, but I have used the redirect method without problem.

Where in the Facebook Ad Campaign rules is it written that the ad can't land on a redirect?

This is what I found written about redirects & tracking:
Make sure than any tracking URL properly redirects to your desired landing page.
  • Watt
  • 2/7/2012 12:57:09 PM
Waw great article. Its answer to my all questions and the code work fine. The P3P header is a good solution for IE.
Thx !!
Terrific Article Eivind. One question about setting up a goal:

my Facebook iFrame Tab Page has form, and the submit button redirect them to paypal. After they use paypal, they're automatically redirected to a thank you page on my site.

I want to set up goal tracking in Google Analytics by putting the analytics tracking code on the html page that is used for the content of my Facebook iFrame Tab Page. That content (displayed in the iframe) will the first required step in my goal funnel.

Will this work? That is, when someone visits my Facebook iFrame Tab Page, can Google detect that content from my site was used for that iframe?
  • Ludo
  • 6/27/2012 11:25:47 AM
Hello Einvind,

Thank you for this article, very clear !

One simple question : does your method also works for Facebook Canvas Apps ?

Very interesting article, Eivind; arrived to this page searching for "how to crawl and index iframes on facebook fan pages”.

You can see your iframe in GA, but the SERPS dont show the content of it.

Do you know a way to make the spiders crawl and index iframes on facebook fan pages?

  • Les
  • 3/12/2013 10:59:45 PM
Hello Eivind,

Thank you for this documentation. Do you have a recommended optimal way to distinguish pageviews, events, etc.. that take place within the facebook iframe from those that take place on the regular site, where the facebook iframe is just calling pages on the regular site?

Thank you,

XClick to move the comment field