Skip to main content
Squash Apps — CTO-led custom software & AI development
← All articles

AngularJs SEO with Prerender.io

9/27/2016 · Kiruthika H.
AngularJs SEO with Prerender.io
Built a beautiful, snappy, user-friendly website using AngularJS, and now you want more users to start browsing it. But, AngularJS which fully embraces the asynchronous model creates problems for Google’s crawlers and this is how the google indexes an angularJs sites: Obviously, this is not what you want your users to view. Now what do we do? Thought a lot :roll: but still no success???? :-( Nevermind :-) , here's how to get your site to the top of the search results. Lets start  by setting up your prerender server : 1.git clone https://github.com/prerender/prerender.git. Then cd Prerender, to go to the directory 2. npm install Instal module dependencies 3. node server.js Run the service (available nohup node server.js & so that it runs in the background)

Client Side: Follow Google's Javascript crawling protocol with hashbang

For reference, the full protocol is here.

Google's Javascript crawling protocol is meant for websites that render using Javascript or need to wait on AJAX calls to complete. If you follow Google's protocol, Google will send a request to your server with a modified url so that you can return the static HTML version of the page rendered by prerender server. Here's how:

If you use urls with #

Nothing after the hash in the url gets sent to your server. Since Javascript frameworks originally used the # as a routing mechanism, that's the main reason why Google created this protocol. Change your urls to #! instead of just using #.
angular.module('exampleApp').config([
    '$locationProvider',
    function($locationProvider) {
        $locationProvider.hashPrefix('!');
    }
]);
Google looks for #! urls and then takes everything after the #! and adds it as a query parameter called _escaped_fragment_. That way, Google effectively fixes the problem of everything after the hash not being sent to your server. Google finds urls like this: http://www.example.com/#!/product/123 Google sends a request to your server like this: http://www.example.com/?_escaped_fragment_=/product/123 , intercept the request on the nginx server like this (imagine the prerender server resides on port 3000 whereas your backend server on port 4000) :
server {
 listen 80;
 server_name www.example.com example.com;
 location ~* / {
   set $prerender 0;
   if ($http_user_agent ~* "baiduspider|
       twitterbot|facebookexternalhit|
       rogerbot|linkedinbot|embedly|
       quora link preview|showyoubot|
       outbrain|pinterest|slackbot") {
   set $prerender 1;
 }
 if ($args ~ "_escaped_fragment_") {
   set $prerender 1;
 }
 if ($uri ~ ".(js|css|xml|less|png|jpg
     |jpeg|gif|pdf|doc|txt|ico|rss|zip|
     mp3|rar|exe|wmv|doc|avi|ppt|mpg|
     mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|
     swf|dat|dmg|iso|flv|m4v|torrent)") {
   set $prerender 0;
 }
 if ($prerender = 1) {
  rewrite .*/$scheme://$host$request_uri?break;
  proxy_pass http://localhost:3000;
 }
 if ($prerender = 0) {
   proxy_pass http://localhost:4000;
 }
}
Thats it! SEO issue solved Now you're well on your way to lots of new users, courtesy of the search engines! Good luck  ;-)
KH

Kiruthika H.

Squash Apps engineering team

Work with us

Building something similar?

Tell us what you're working on. We'll propose a team structure and cost estimate on a 15-minute call — no sales pitch, no hand-off.

Book a free 15-min call →

No commitment · Reply within 24 hours · NDA available

Book a 15-min call