How to track campaigns leading to Facebook tab

So you have a Facebook Page set up with some custom tabs. One fine day you want to start an ad campaign to drive traffic directly to one of these tabs. You run into a problem how to track ad campaigns pointing at custom Facebook tab. Well here’s how to track.

First of all you need a custom Facebook tab to track. There is a pretty neat tutorial how to create a custom tab for a Facebook Page so just follow it to get one. In this example I’m going to add tracking to „Request a Product Demo“ custom tab that sits on Campalyst Facebook Fan Page.

Here’s how the custom tab “Request Product Demo” looks on Campalyst Fan Page.

When a user clicks on the logo to request a demo he ends up on URL of the tab:

For all users arriving to this URL Facebook will generate a page with Facebook header and a large iframe. Inside this iframe a page from our own server is loaded. The URL of this page is configured when the tab is installed on a Page. In our case the URL of the page is:

This page is tracked using Google Analytics. Our goal is to separate the organic traffic (people clicking on the tab on our timeline) from what the ads generated. When the user came via ad we want them internally to end up in an url with some additional tracking parameters:

We cannot just add the utm codes to the end of the URL of the tab, it wouldn’t work. We have to use an easy trick and add a couple of lines in front of our custom tab PHP code.

First we need two new symbols to replace = and &. I chose ! and $ respectively as they are both in the list of allowed chars of an url and also quite rarely used inside parameters. Now the URL of the tab becomes:!c3$utm_medium!fbads

Notice how = has been replaced with ! and & has been replaced with $ and our additional params have been set as value of app_data param of the tab url.

Next part is to have PHP code in place to read and parse value app_data. Facebook passes on this data to us in a signed format. We add the following script on top of PHP script to catch and decode the parameters:

// symbols we use instead of = and &
$replacements = array(
	'=' => '!',
	'&' => '$',

$redirectUrl = $_SERVER['REQUEST_URI']; // current page

if (!empty($_POST['signed_request'])) {
	list($sig, $payload) = explode('.', $_POST['signed_request'], 2);
	$decoded = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);

	if (isset($decoded['app_data']) ) { // additional parameters exist
		$search = array_values($replacements);
		$replace = array_keys($replacements);

		$customParams = str_replace($search, $replace, $decoded['app_data']);
		$redirectUrl .= '?'.$customParams; // add decoded params
	header("HTTP/1.1 303 See Other");
	header('Location: '.$redirectUrl);

What happens here is that when Facebook is loading our page inside an iframe then it makes a post request with the app_data parameters encoded into signed_request. We decode them and make a redirect to the page itself followed by the decoded parameters where ! and $ have been replaced again with = and &. On the page we have Google Analytics set up to catch the decoded utm tags from the url.


3 thoughts on “How to track campaigns leading to Facebook tab

  1. Dee says:

    Do you experience and problems with facebook not returning the signed_request for each user that clicks on an ad? I have this problem

  2. Dee says:

    thanks, something similar, app_data is returned for my user and several others but mostly it is blank, very strange

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: