Search code examples
angularjsparse-platformweb-crawlergoogle-crawlersprerender

Making AngularJS and Parse Web App Crawlable with Prerender


I have been trying to get my AngularJS and Parse web app crawlable for Google and Facebook share and even with prerender-parse I have not been able to get it working. I have tried using tips from this Parse Developers thread for engaging HTML5 Mode. Nothing will work using the Facebook URL debugger or Google Fetch Bot. Can anyone share a full step by step setup that they have used and is currently working?


Solution

  • After some help from Prerender.io team, here are the outlined steps that resulted in successful crawling by the Facebook and Google crawler tests. Remember this is for an AngularJS app running on a Parse.com backend

    1. add $locationProvider.hashPrefix("!") to your .config in your main module (I am not using HTML5Mode because it causes issues when manually entering urls).

    2. add prerender-parse to the TOP of your cloud/app.js and implement prerender-parse according to the instructions found here

      var express = require('express'); var app = express(); var parseAdaptor = require('cloud/prerender-parse.js'); app.use(require('cloud/prerenderio.js').setAdaptor(parseAdaptor(Parse)).set('prerenderToken','YOUR_PARSE_TOKEN'));

    3. add <meta name="fragment" content="!" /> to the <head> of your index.html

    Bonus - dynamic metadata from child controllers for crawlers:

    B1. Add a controller with event to your main app if you don't already have one.

    <html lang="en" ng-app="roommi" ng-controller="MainCtrl">`
    
    .controller('MainCtrl', ['$rootScope', '$scope', '$state', '$stateParams', function($rootScope, $scope, $state, $stateParams) {
        $scope.$on('metaUpdate', function(event, metadata) {
            $scope.metadata = metadata;
        });
    }
    

    B3. In your child controller set your metadata object and call the $emit function to cast the event to the MainCtrl.

    $scope.$emit('metaUpdate', metadata);

    B4. Now you can add all of the metadata to your head in your index.html

    <meta  property="og:url"             content="{{metadata.url}}"/> 
    <meta  property="og:title"           content="{{metadata.title}}"/> 
    <meta  property="og:image"           content="{{metadata.image}}"/> 
    <meta  property="og:description"     content="{{metadata.desc}}"/>`
    

    B4. One caveat is that this method does not control the timing of the cache by prerender.io. So only basic queries and data manipulation can be performed before the population of the metadata object. If someone figures out a good way to deal with timing, let me know. I tried the window.prerenderReady method provided by prerender.io, but it did not work in a few configurations I tried.