{"id":2067,"date":"2014-01-07T20:21:18","date_gmt":"2014-01-07T20:21:18","guid":{"rendered":"http:\/\/www.sitekickr.com\/blog\/?p=2067"},"modified":"2014-01-07T20:21:18","modified_gmt":"2014-01-07T20:21:18","slug":"dealing-facebook-page-tab-width","status":"publish","type":"post","link":"https:\/\/www.sitekickr.com\/blog\/dealing-facebook-page-tab-width\/","title":{"rendered":"Dealing with the Facebook Page Tab Width"},"content":{"rendered":"<p>It&#8217;s becoming more common for client&#8217;s to ask me to embed their web apps or sites into Facebook Canvas pages. If you aren&#8217;t familiar with these, it&#8217;s really just an IFrame within Facebook, which loads any URL that you provide to it.<\/p>\n<p>The catch is that Facebook limits the width of the IFrame to a maximum of 810 pixels. If your site or app was developed in a responsive fashion, this usually works out well. If it wasn&#8217;t, you find yourself making various layout tweaks to make sure everything fits inside this width.<\/p>\n<p>If you know in advance that your site will be used within a Facebook Canvas page, you&#8217;d be smart to follow the best practices for developing a responsive site. But you may not always have that insight, or you may need to retrofit an existing site to work with this narrowed width.<\/p>\n<p>I find that the easiest approach is to create a separate stylesheet to adjust the site layout to fit within 810 pixels. Then, simply apply the stylesheet when your site is loaded within Facebook. It&#8217;s as simple as supplying a query string parameter, indicating that your site is loaded within a Facebook frame, i.e.<\/p>\n<p>http:\/\/www.mysite.com\/?fb=1<\/p>\n<h3>Complete website within a Canvas page.<\/h3>\n<p>If you need to embed an entire website into a Facebook Canvas page, the plot thickens a bit. While you can provide a query string parameter for the first page, what happens when the user clicks to another link. The query string parameter is dropped and the Facebook IFrame stylesheet isn&#8217;t loaded.<\/p>\n<p>You could ensure that all links get the ?fb=1 parameter appended to them, but that&#8217;s tedious and sloppy.<\/p>\n<p>We can leverage server-side session storage to help us out. The flowchart below will illustrate the process I used in a recent job.<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-2077\" alt=\"facebook canvas page\" src=\"http:\/\/www.sitekickr.com\/blog\/wp-content\/uploads\/2014\/01\/fb_canvas_page.png\" width=\"429\" height=\"490\" srcset=\"https:\/\/www.sitekickr.com\/blog\/wp-content\/uploads\/2014\/01\/fb_canvas_page.png 429w, https:\/\/www.sitekickr.com\/blog\/wp-content\/uploads\/2014\/01\/fb_canvas_page-262x300.png 262w\" sizes=\"(max-width: 429px) 100vw, 429px\" \/><\/p>\n<p>And, since the site I did this for was developed in Zope, here&#8217;s a piece of sample code that about 1% of you will understand!<\/p>\n<pre class=\"prettyprint\"><code>&lt;tal:x condition=\"request\/fb|nothing\"&gt;\r\n    &lt;tal:y define=\"dummy python: request.SESSION.set('fb', request.get('fb'))\" \/&gt;\r\n&lt;\/tal:x&gt;\r\n&lt;link rel=\"stylesheet\" id=\"fb-style\" href=\"\/assets\/css\/facebook-iframe.css\" \r\n      tal:condition=\"python: request.SESSION.get('fb', request.get('fb', 0))\" \/&gt;\r\n<\/code><\/pre>\n<p>&nbsp;<\/p>\n<h3>Busting out of the Facebook Canvas Page<\/h3>\n<p>So that&#8217;s fairly straightforward. But, what happens if your user wants to break free of the iFrame and load your website independent of Facebook?<\/p>\n<p>You might think that simply supplying a link with a target of &#8220;_blank&#8221; or &#8220;_parent&#8221; would do the trick. But, we can&#8217;t forget about the session variable we put in place. It will still be active whether the site is within an iFrame or not.<\/p>\n<p>While I&#8217;ve devised a plan to tackle this scenario, I have yet to implement it. So, take this as theory alone and use it only as a guide:<\/p>\n<ol>\n<li>On every page, use JavaScript to see if the website is being loaded in an iFrame.<br \/>\nIf it is not in a frame, check to see if the stylesheet exists. If it does exist, reload the page with a different query string parameter.Now you&#8217;ll see why I included an ID attribute on the stylesheet link above.<\/p>\n<pre class=\"prettyprint\"><code>if (window === window.top &amp;&amp; document.getElementById('fb-style')) {\r\n    location.href = '?reset=1';\r\n}<\/code><\/pre>\n<\/li>\n<li>If the <strong>reset<\/strong> query string parameter is detected, remove the <strong>fb<\/strong> session variable.<\/li>\n<\/ol>\n<p><a href=\"http:\/\/www.sitekickr.com\/blog\/wp-content\/uploads\/2014\/01\/fb_canvas_page_bust_out.png\"><img loading=\"lazy\" class=\"alignnone size-full wp-image-2082\" alt=\"break out facebook iframe\" src=\"http:\/\/www.sitekickr.com\/blog\/wp-content\/uploads\/2014\/01\/fb_canvas_page_bust_out.png\" width=\"422\" height=\"482\" srcset=\"https:\/\/www.sitekickr.com\/blog\/wp-content\/uploads\/2014\/01\/fb_canvas_page_bust_out.png 422w, https:\/\/www.sitekickr.com\/blog\/wp-content\/uploads\/2014\/01\/fb_canvas_page_bust_out-262x300.png 262w\" sizes=\"(max-width: 422px) 100vw, 422px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you know in advance that your site will be used within a Facebook Canvas page, you&#8217;d be smart to follow the best practices for developing a responsive site. But you may not always have that insight, or you may need to retrofit an existing site to work with this narrowed width.<\/p>\n","protected":false},"author":1,"featured_media":2083,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"amp_status":""},"categories":[101],"tags":[102],"_links":{"self":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/2067"}],"collection":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/comments?post=2067"}],"version-history":[{"count":7,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/2067\/revisions"}],"predecessor-version":[{"id":2084,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/posts\/2067\/revisions\/2084"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/media\/2083"}],"wp:attachment":[{"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/media?parent=2067"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/categories?post=2067"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sitekickr.com\/blog\/wp-json\/wp\/v2\/tags?post=2067"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}