Wednesday, February 19, 2014

SEO - Single Page Websites

In this article, we will see how to optimized the ranking of your single page application. Today, the single page website development is really common. It exists a lot of frameworks to create single page website like AngularJS, BackboneJS...

But the problem when you try to index your website in Google or Bing, just the html page will be index. That means just 1 entry with only 1 title and description. It is not really good  if your website is composed of many pages.

Adapt your webapp

Google provides a solution to crawl the dynamically created content :
  • Don't use only the # as Hash fragment, replace it by #!
    • Google will replace the hash fragment with exclamation mark by _escaped_fragment_
    • http://www.exemple.com/#toto => http://www.example.com/#!toto
    • Url GoogleBot : http://www.example.com/?_escaped_fragment_=toto
  • Add a trigger to the head of the HTML of a page
    • <meta name="fragment" content="!">
Now Google or Bing will be able to crawl all the page of your website.  The next step is to return the html page or content for the good hash fragment.

Adapt your Backend

If you use NodeJs to host you webapp my suggestion is to read this good post : Easily index your SPA thanks to PhantomJS

In my case, I could not use this trick because my single page app is hosted on Apache and I can not install external tools...
So my solution is to use the .htaccess to create a redirection on pre-render pages. To pre-render a page you can use PhantomJS or an other tools to create a html file for each page. 

You can create an automatic script to generate these pages. Also you can modify the title and the description meta tag for each page.
After create a folder seo/ on your server, hosted all your html pages on it. 

.htaccess

Create the .htaccess file in your root folder, with this following content :

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$
RewriteRule ^(.*)$ seo/%1.html [NC,L]
</IfModule>

This code means if the url contains _escaped_fragment_=, we redirect the call to the prerender html page.
The html must have the same name of your hash fragment toto.html in my previous example.

You can test your rule with the "Fetch as Google" in Crawl menu on Google Webmaster Tool.

Now Google, Bing and the other can index all the pages of your single page application!!!

Sources : Google specification Ajax Crawling