Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prerender.io Not Working in Production

I'm trying to get my MEAN stack app set up for proper SEO, using the prerender.io middleware. Locally, everything is working great. In production, nada.The app is hosted on OpenShift. I'm using environment variables for the preRenderToken and preRenderServiceUrl (the service URL is only for dev, and points to another local node server).

In /server/config/local.env.js:

(function()
{
    'use strict';

    module.exports = Env();

    function Env()
    {
        var IEnvironmentVariables = {

            // Prerender.io
            PRERENDER_SERVICE_URL: 'http://localhost:3000/',
            PRERENDER_TOKEN: 'my prerender.io token',
        };

        return IEnvironmentVariables;
    }

})();

In /server/config/environment/index.js:

// Prerender.io
// I've definitely got both of these set locally and the token set on OpenShift
prerenderServiceUrl: process.env.PRERENDER_SERVICE_URL || process.env.OPENSHIFT_PRERENDER_SERVICE_URL || 'http://localhost:3000/',
prerenderToken: process.env.PRERENDER_TOKEN || process.env.OPENSHIFT_PRERENDER_TOKEN || 'prerender-token'

The document head contains the following meta tags:

<meta name="fragment" content="!">
<meta name="description" content="{{description}}">
<meta name="keywords" content="{{keywords}}">

These bound expressions are set on Angular's $rootScope like this:

(function()
{
    'use strict';

    angular.module('myApp')

    .run(['$rootScope', '$state', Run]);

    function Run($rootScope, $state)
    {
        $rootScope.$on('$stateChangeSuccess', function (event, current, previous) 
        {

            // Meta tags
            $rootScope.description = $state.current.description || 'default-description';
            $rootScope.keywords = $state.current.keywords ? 
            $state.current.keywords
            .toString()
            .split(',')
            .join(' ') : 'default-keywords
        });

    }

})();

Finally, in each $state configuration, something like this:

(function()
{
    'use strict';

    angular.module('myApp')

    .config(['$stateProvider', Config]);

    function Config($stateProvider) 
    {
        $stateProvider

        .state('main', {
            url: '/',
            templateUrl: 'app/main/main.html',
            controller: 'MainController',
            controllerAs: 'vm',
            description: 'my site description',
            keywords: ['array', 'of', 'keywords']
        });
    }

})();

Visiting http://localhost:9000/?_escaped_fragment= (or any other site pages with that query string) produces the pre-rendered page, with the proper values in the meta tags. In production, I'm able to visit http://www.dancakes.com/?_escaped_fragment= but the page is not pre-rendered (that is the actual site URL if you want to verify).

I've toyed around with placing the app.use(prerender . . .) statements in different positions, and each time I end up with something that works locally, and either partly or not at all in production.

like image 654
Justin Avatar asked Mar 25 '26 08:03

Justin


1 Answers

So, it seems that you need underscore after fragment ?_escaped_fragment_=

like image 170
YOU Avatar answered Mar 26 '26 22:03

YOU



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!