How to setup prerender.io on my MEAN stack application running behind Nginx?

May 8, 2015 4k views
MEAN Nginx Node.js

I have a Node application running behind Nginx on port:9000. My current nginx config file (/etc/nginx/conf.d/puanjai.com.conf) looks like so..

    server {

     listen 80;

    server_name puanjai.com www.puanjai.com; 

    location / {
        proxy_pass http://localhost:9000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
      }
    }

However, in Prerender.io's documentation, (https://prerender.io/documentation) there is snippet for both Node and Nginx. And my guess is that I should use Nginix. And for Nginx, it tells me to use the snippet below which I have no idea how to integrate the following code with my current one to make things work.

https://gist.github.com/thoop/8165802

server {
    listen 80;
    server_name puanjai.com www.puanjai.com;

    root   /path/to/your/root;
    index  index.html;

    location / {
        try_files $uri @prerender;
    }

    location @prerender {
        #proxy_set_header X-Prerender-Token wGvPrLPdSuDSpoxyOa46;

        set $prerender 0;
        if ($http_user_agent ~* "baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
            set $prerender 1;
        }
        if ($args ~ "_escaped_fragment_") {
            set $prerender 1;
        }
        if ($http_user_agent ~ "Prerender") {
            set $prerender 0;
        }
        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|ttf|woff)") {
            set $prerender 0;
        }

        #resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
        resolver 8.8.8.8;

        if ($prerender = 1) {

            #setting prerender as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
            set $prerender "service.prerender.io";
            rewrite .* /$scheme://$host$request_uri? break;
            proxy_pass http://$prerender;
        }
        if ($prerender = 0) {
            rewrite .* /index.html break;
        }
    }
}
2 Answers

You should be fine with this config:

server {
    listen 80;
    server_name puanjai.com www.puanjai.com;

    root   /path/to/your/root;
    index  index.html;

    location / {
        try_files $uri @prerender;
    }

    location @prerender {
        #proxy_set_header X-Prerender-Token wGvPrLPdSuDSpoxyOa46;

        set $prerender 0;
        if ($http_user_agent ~* "baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
            set $prerender 1;
        }
        if ($args ~ "_escaped_fragment_") {
            set $prerender 1;
        }
        if ($http_user_agent ~ "Prerender") {
            set $prerender 0;
        }
        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|ttf|woff)") {
            set $prerender 0;
        }

        #resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
        resolver 8.8.8.8;

        if ($prerender = 1) {

            #setting prerender as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
            set $prerender "service.prerender.io";
            rewrite .* /$scheme://$host$request_uri? break;
            proxy_pass http://$prerender;
        }
        if ($prerender = 0) {
            proxy_pass http://localhost:9000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }
}

The relevant part for you is inside of this if:

if ($prerender = 0) {
    ...
}

Where I put the proxy logic for your node app.

Hi,

I just tried the solution above and it doesn't work. Within the last condition:

if ($prerender = 0) {
    #the directives
}

When saving my Nginx config file and then running the test with 'sudo nginx -t' the file is invalid and it tells me the following:

nginx: [emerg] "proxy_http_version" directive is not allowed here in /etc/nginx/sites-enabled/annachristoffer:48
nginx: configuration file /etc/nginx/nginx.conf test failed

What I am trying to do is to get my production meteor app running with prerender.io and cannot get it working. Has anyone else encountered the same issues and if so, how did you go about solving them?

Have another answer? Share your knowledge.