Never develop for Facebook canvas

Some time ago we started a project (like a social game) mainly targeting Facebook audience. We decided to base it on Facebook Canvas technology, not to be confused with canvas.facebook.com, which is business presentation layout. Basically it loads your web application into iframe inside the familiar Facebook user interface page on an URL like https://apps.facebook.com/{your-application-machine-name}.

At first, it seemed to be a cakewalk and the technology matching our expectations just right:

  1. The users are presented with a Facebook interface they are already familiar too.
  2. The users doesn’t have to login if they are logged in to Facebook. They just have to sign up to the application the very first time they access it.
  3. We can use Facebook’s Invitation Dialog that sends game invitations to selected Facebook friends of the user.
  4. We can use Canvas Payment service instead of implementing some payment gateway support in our application.
  5. We can automatically create Facebook groups for user teams in our application.

But when we started to dive more and more deeper into Facebook Canvas development, the disadvantages started to show up one by one:

  1. It required us to host our application (what is loaded into the iframe) on SSL URL so we had to buy an SSL certificate. While not a big deal and good for security but why SSL is also required for a test version of the application?
    Facebook allows registering a test version(s) of your canvas application with different URL(s), which can point to local host the hustle for code testing. But it’s all ruined by this SSL requirement so you end up telling your browser https://127.0.0.1/ is safe even with self-created certificate. Honestly speaking, I failed to solve this issue permanently for Google Chrome browser on Windows even after adding my certificate to white list following some guidelines I found on the web.
  2. The whole Facebook Canvas system seems to be not developed for web applications with link transitions and POST forms. I think they targeted mainly Flash or JS applications that always stay on the same URL.
    If you refresh the iframe or follow some link, it will lost all the Facebook authentication data. So we had to save the login data in user session on our side and restore on page load if original Facebook data is not available. AFAIK, this may not work for some old IE version that do not save cookies for iframes.
  3. Another thing is that the URL in your browser stays the same when you surf between application pages in the iframe so if you refresh the Facebook page, you will go back to the application’s page you started with. At the same time, Facebook allows coding application local paths into Facebook Canvas URL like: https://apps.facebook.com/{your-application-machine-name}/{path-inside-your-application}. So, if you open an URL like https://apps.facebook.com/{your-application-machine-name}/my/test/page it will load https://{your-application-base-URL}/my/test/page into the iframe.
    I ended up implementing a JS trick that intercepted any link lick event and reloaded the main frame of the browser with corresponding Facebook URL. This is what I didn’t like the most: a JS failure or slow page load may cause the user to click an original link.
    Still I had to save login data to user session in order to restore it after POST request sent by any form in my application. This approach did not allow having form targets reside on URLs different to the current page but that was fine to me.
    Those could be considered a root issues of using the iframe tag to load the Canvas application but why aren’t they all documented?
    All in all it seems that you should better use pjax or any similar JS technology to process requests and update the application page w/o doing a n iframe reload actually.
  4. While Facebook have a mobile version m.facebook.com, there is nothing like that for apps.facebook.com. It doesn’t matter you made a responsive layout in your application, the whole page still uses a desktop layout making your page inside iframe use it too. This makes mobile user see a conventional desktop Facebook page with sidebars and menus, zoomed out to fit inside tiny mobile device screen. This is just unacceptable.
  5. Facebook Canvas for Games have a nice feature called invitations. The user could pick some of his or her Facebook friends and send them invitation messages, which will bring them to the game if clicked. The invitation messages will appear below the Notifications (globe) icon on the Facebook menu when you click it. This is just nice and you know what? The invitation messages are completely not shown in mobile version of Facebook (m.facebook.com) and in mobile Facebook application. Everything else is shown but not the game invitations. And as Facebook support answered, this is not a bug, it’s a “feature”. They don’t want to annoy mobile users with Canvas game invitations assuming Facebook Canvas is not for mobile devices at all.
    Taking into account that most of our users accessed Facebook via mobile devices, we had to fallback to old-style email invitations for recipient addresses manually entered by the user.
  6. The invitation dialog itself is a complete disaster. It shows “Send” button right to each friend on your list but it doesn’t actually send anything until you click the OK button in the bottom of the dialog which is very hard to notice. So many times our users fall into this mistake thinking they invited their friends while no invitation was on the way. And as the dialog is provided by Facebook, we could not alter it much. The worst problem there is not other way your application may message the users who didn’t yet signed up to the application.
  7. Another issue with the Invite Dialog is that it doesn’t indicate the users you already invited resulting in duplicate invitations sent to the same user.
  8. Facebook Canvas have also a nice feature called Canvas Payments. With a few lines of JS code you can accept payments from wide variety of services: PayPal, credit cards, mobile payments, etc. But it all goes for a price of draconian 30% commission, which we didn’t notice when we made the decision to use the service. It turned out our application could not commercially success with such a high rate for processing payments.
  9. Another problem with Canvas Payments is that it only works in one direction: from the user to the Facebook (and eventually to your bank account). If you want the users to monetize their achievements in your game, you should pick another service like PayPal at least for payouts.
  10. And finally the application groups feature went deprecated this year without any replacement provided. So you cannot generate Facebook groups and invite members from your application anymore. This is quite sad as we just loved the feature for hosting internal conversations or team members within our game.

Conclusion

Facebook Canvas seems to be a good way to promote your application if it is already successful as a web or mobile application. At any way it shouldn’t be considered as the primary publication platform unless for a simple one-page application. You should consider Facebook Canvas for providing as a limited version of your application or just as a gateway to it. The whole Facebook Canvas platform seems to be ageing and it looks like Facebook may abandon it later either completely or partially.

You shouldn’t use Facebook Canvas Payments if small commission rate is critical for your commercial success. If you’re going to allow users monetize their achievements or get paid for anything else, you should consider a different service like PayPal.

You should have a mobile (Android/iOS) application if you’re targeting mobile users. Facebook allows some integration with the mobile application(s) you specify in your Canvas application profile.

All in all, it turned out that for us it would better if we developed a stand-alone web application with Facebook Login function and PayPal payments instead of relying on Facebook Canvas and Canvas Payments. It was a huge failure but I hope somebody will learn from our mistake.

Admintasia: awesome design template for web applications

PS. The post was written so long time ago. Now I’m happy we can simply use Twitter Bootstrap and get working application/site design in seconds.

Unlike desktop applications which rarely use “skins”, web applications look ugly and unprofessional w/o a design template. However, building unique design for each project sometimes is just not affordable, especially for back-end, admin and other data analysis and management applications. At the other hand, if you look for free or commercial design templates available, you’ll find nothing but website templates which doesn’t have elements like cascading menus, dialog, grid, form elements and others usually required for an application user interface.

Sad but true, except this little thing: Admintasia 2.1. Powered with jQuery and jQuery IU it has all the elements you need to build rich professional user interfaces.

Read more

PDFmyURL: export web pages with JavaScript elements to PDF on shared hosting

Customers and users sometimes ask for an ability to save some reports from web applications to PDF files. It could be very tricky to write PDF directly but as far as you already have those reports on web pages you can add printable views of them and then ability to convert HTML/CSS of the pages to PDF, say with dompdf library.
This way you can hit two targets: add printing of reports and PDF export. Dompdf is still in beta but at least it could work on shared hosting AFAIK.

But what if you need to export web pages with JavaScript canvas elements like Flot charts that are plotted on browser side only? All available solutions require installing executables which is usually problematic on shared hosting.

The solution is PDFmyURL.com/ which you can easily use as a web-service: send GET requests with URL of the page you want to export and get PDF file as a response. The service is based wkhtmltopdf. As you can see, it’s good enough to convert pages with Flot charts:

http://pdfmyurl.com/?url=http://people.iola.dk/olau/flot/examples/basic.html.

You can call the service from JavaScript on your pages or from server-side scripts via any HTTP client library like cURL. All wkhtmltopdf options are supported and could be passed as GET request parameters.

Their free service inserts very small watermark to each page which is usually not a problem. But of course you can upgrade to paid service to remove it.

Rewriting for SEO-Friendly URLs: .htaccess or PHP?

Modern database driven web sites implement SEO-friendly URLs emulating static directories and files. Switching to such “clean” URLs enables good indexing by search engines, makes URLs more user-friendly and hides the server-side language. For example, this clean URL may refer to the page in some product directory:

http://somesite.com/products/network/router.html

In fact, there is no /products/network folder on the server and no router.html file at all. The page is generated by server script using database query for “network” product category and “router” product. But who calls the script and where it gets the query parameter values?

This technique is usually referred as “URL rewriting”. It allows web server to recognize what information was requested by parsing the URL string. Apache and PHP allow multiple options to implement URL rewriting. So which one is the best?

Read more

SEO-friendly URLs and relative links

The Web community is going crazy about SEO-friendly URLs like http://somesite.com/products/network/router/. Well, it looks much better than a script URL http://somesite.com/products.php?c=network&p=router which may actually serve the page behind the scenes. There are a lot of good articles on how to implement SEO-friendly URLs, for example this one or my own post. But they do not warn the reader about one usual problem: once you have updated your site to handle virtual paths you will probably get a bad surprise:

CSS, image and internal page links are totally broken!

Why? Because those links are usually relative to the page location. The browser has no idea about virtual folders and tries to get files from locations relative to the page URL context. For example, if there is a usual CSS link in the page header:

<link rel="stylesheet" href="style.css" type="text/css" media="screen" />

Then the browser will try to download non-existing file http://somesite.com/products/network/router/style.css and fail silently. No CSS style will be applied.

It’s incredible how many words were spoken about SEO-friendly URLs with almost no word about this relative link problem.
So, what you have to do? Don’t worry, there are multiple solutions available and I’ll try to explain them all.

Read more