Facebook Apps can live inside or outside Facebook. Inside Facebook they can live in the Canvas or in a Page Tab. It is important to be able to detect these modes to provide a customized experience. Although the documentation is pretty clear, I feel it is useful to make some notes here how this works.

featured image

According to the Canvas documentation "whenever your application is loaded within a Canvas page, Facebook will make an HTTP POST to your Canvas URL. This request will include a POST variable called signed_request.". For Page Tabs this works similarly: "When a user selects your Page Tab, you will receive the signed_request parameter with one additional parameter, page. This parameter contains a JSON object with an id (the page id of the current page) ..."

It is the signed_request parameter I will focus on in this post. I will show you how to get the necessary information out of it and show examples how to use it to determine the flow of your app.

Why is this useful?

In this post I will give you two examples how this can be useful:

  • 1. get rid of the vertical scrollbar in ONLY the Canvas version of My Reading List
  • 2. identify within a page tab application what Facebook page id it runs in to deliver specific content based on that page id.

How to parse the signed request?

You can do it manually with this PHP code example or use Facebook's PHP SDK. Facebook requires your app's Secret to ensure the request was sent by Facebook and not by a third party. The response will yield a JSON object, something like:

In the canvas:

signed request response inside the canvas

And in a page tab:

signed request response inside a page tab

Practical examples:

1. My Reading List

For My Reading List (and any app for that matter) I typically want to get rid of the vertical scroll bar in the canvas. One way to do this is with Facebook's Javascript SDK's method: FB.Canvas.setAutoGrow() (another method is FB.Canvas.setSize). Additionally you set the CSS property "overflow" to "hidden" on the body tag.

However doing this makes the "standalone" (outside Facebook) non-scrollable which presents a problem.

So a solution is to ask the App if it is in the Canvas, example in PHP:

<?php
if (canvasMode($fb_secret)) {
  echo "<body style='overflow:hidden;'>";
} else {
  echo "<body>";
}
..
..
function canvasMode($secret){
  $canvas = false; 

  if( isset($_REQUEST['signed_request']) ) {
    $data = parse_signed_request($_REQUEST["signed_request"], $secret);
    if( $data ) {
      $canvas = true; 
    } 
  } 

  return $canvas;
}
?>

... and the result is I have the best of both worlds:

1. inside the Facebook Canvas: no scrollbar

inside Facebook = no scrollbar

2. outside of Facebook, overflow is not set to "hidden" on the body, hence the content is scrollable (default html rendering):

outside Facebook = scrollbar

2. Dynamic content in page tabs

Page tabs is a cool feature I recently learned about. It allows you to attach a Facebook app to a Facebook Page. Facebook makes this really easy as you can read here.

Again, you can leverage the signed request response to tell your app on which Facebook page it is running. This way you can load different content on different pages that have the Page Tab app installed.

To illustrate this, we can use the same code as above, however we are looking for the page id bit in the JSON object:

<?php
..
$signed_request = parse_signed_request($_REQUEST['signed_request'], $secret);
$pageId = $signed_request['page']['id'];
..
?>

Now you can match this page id against for example a database which holds different content for every Facebook page (id).

Conclusion

Standalone (outside Facebook) apps, Canvas and Page Tab apps are different in nature so it is important to identify when you are operating in one or the other.

The Facebook SDK or the raw code example Facebook provided, suit this purpose quite well. Once you parse the signed request you can influence the way the App works in every instance (environment).

If you have interesting use cases, other than the two examples shown in this post, feel free to share them in the comments.


Bob Belderbos

Software Developer, Pythonista, Data Geek, Student of Life. About me