Friday, March 29, 2024
HomePythonEasy methods to Prerender React Apps Utilizing Prerender

Easy methods to Prerender React Apps Utilizing Prerender


Hello everybody! 👋 I’ve been engaged on a sports activities analytics startup and the entire front-end is made utilizing React. I haven’t needed to work on such a giant React mission earlier than this and so it introduced alongside some distinctive challenges. Up to now, search engine marketing hasn’t been a giant subject for the online initiatives I’ve labored on. I may at all times simply add related knowledge to the meta tags, outline the navigation utilizing semantic HTML tags and Google would present the web site appropriately on its consequence pages. Nonetheless, this time, the entire web site was being generated utilizing client-side Javascript. On preliminary load, there may be near nothing on the internet web page and the navigation turns into accessible solely when JavaScript is executed.

Despite the fact that Google crawler can execute Javascript, it’s a higher search engine marketing observe to serve it a rendered software as an alternative of counting on it to render the appliance by itself. Furthermore, if the rendering takes longer than some set time, the crawler would merely transfer on. On this article, I’ll present you methods to get the prerender service up and working in your server and serve it by way of NGINX to completely different bots and increase your search engine marketing.

On the lookout for an answer

I searched round and located a number of options to this downside. Sure node scripts may very well be run as a post-processing step and they’d output a rendered React app. I attempted utilizing them however none labored flawlessly with out requiring me to tweak the app code considerably. It’s simpler to include such instruments firstly of a mission. Including them later simply results in numerous ache. I used to be in search of a plug-and-play answer so I saved trying.

I quickly got here throughout prerender. This service acts as a middleware between your software and the end-user. It makes use of Headless Chrome to render HTML. If the end-user is a human, the server will return HTML + JS and the React code can be rendered on the client-side. Nonetheless, if the end-user is a bot then the server will ship the HTML + JS to the prerender service and return the rendered static HTML web page to the bot. There are a number of related providers. I may have simply as simply used renderton however prerender simply appeared extra fashionable so I went forward with that.

Word: It goes with out saying that this may not be probably the most environment friendly answer nevertheless it works for my use case. Your mileage could differ so attempt at your individual danger 😄

That is how a typical stream with the prerender service appears like:

prerender-flow

The prerender service will cache the static HTML for some time earlier than requesting a brand new copy from the server. This methodology didn’t require me to vary something on my React app and solely required me to make some changes to the NGINX server configuration.

That is how my software was being served earlier than prerender got here into the combo:

server-arch

After including prerender, the stream seemed one thing like this:

final-flow

Establishing prerender service

There are two methods you may make use of the prerender service. You possibly can both make use of the paid hosted service (comprises a free plan as effectively) or you’ll be able to run the open supply service in your server and interface with that. I made a decision to go for the latter. Step one was to put in prerender on the server. It was pretty easy to take action utilizing npm:

$ npm set up prerender

The following step was to create a brand new node script that ran the service. These 3 traces are sufficient to get the service up and working:

const prerender = require('prerender');
const server = prerender();
server.begin();

Save this code to a server.js file and run it utilizing node:

$ node server.js

At this level you’ll be able to go forward and take a look at whether or not the prerender service is working appropriately or not by opening http://localhost:3000/render/?url=https://google.com/. This could show the Google homepage. If the pictures don’t present up appropriately, don’t fear. The problem can be fastened after we serve the prerender service by way of NGINX.

Run prerender on system begin

The following step is to run prerender on system begin and ensure it retains working in case of crash or system restart. We are going to make this occur by making a systemd service file. I’m assuming that you simply saved the server.js file in your house folder. My house folder is yasoob however yours is likely to be completely different so be sure you edit the WorkingDirectory path. Create a prerender.service file in /and so forth/systemd/system folder with the next contents:

[Unit]
Description=Prerender server for bot crawling
After=community.goal

[Service]
Person=yasoob
WorkingDirectory=/house/yasoob/
ExecStart=/usr/bin/node server.js
Restart=at all times

[Install]
WantedBy=multi-user.goal

On this file, we’re telling systemd to begin server.js when the community is up and working. The service would launch below the person yasoob and the command it must run is /usr/bin/node server.js. The script would additionally routinely restart in case of a crash or system restart.

After saving this file, let’s ensure that systemd can acknowledge it:

$ sudo service prerender standing

● prerender.service - Prerender server for bot crawling
     Loaded: loaded (/and so forth/systemd/system/prerender.service; disabled; vendor preset: enabled)
     Energetic: inactive (useless)

Excellent! Now let’s begin the service after which test the standing:

$ sudo service prerender begin
$ sudo service prerender standing

● prerender.service - Prerender server for bot crawling
     Loaded: loaded (/and so forth/systemd/system/prerender.service; disabled; vendor preset: enabled)
     Energetic: lively (working) since Thu 2021-01-07 19:59:46 UTC; 2s in the past
   Major PID: 589168 (node)
      Duties: 7 (restrict: 1137)
     Reminiscence: 41.8M
     CGroup: /system.slice/prerender.service
             └─589168 /usr/bin/node server.js

Jan 07 19:59:46 systemd[1]: Began Prerender server for bot crawling.

Integrating prerender with NGINX

Now that our prerender service is working, we will go forward and combine it with NGINX. What we wish to do is that the conventional person must be despatched the conventional HTML + JS response however a bot must be despatched a response by the prerender service.

The unique NGINX configuration file for my React app seemed like this:

server {
    server_name instance.com;
    root /house/yasoob/instance/construct;
    index index.html;

    location / {
  	    try_files $uri /index.html;
        add_header Cache-Management "no-cache";
    }

    location /static {
        expires 1y;
        add_header Cache-Management "public";
    }

    location /api {
        embody proxy_params;
        proxy_pass http://localhost:5000;
    }
}

This can be a pretty generic configuration file. We add some cache headers to sure path responses and move the /api route visitors to the gunicorn server working on port 5000. Now we simply must ensure that all requests made by a bot are responded to by the prerender service that’s working on port 3000. The template file for these adjustments is conveniently offered by the prerender of us. I took the identical file and tweaked it a bit to make it work for my setup. The foremost factor I modified within the template was to edit the prerender service URL and take away the proxy header half. As I’m utilizing a self-hosted service, I changed service.prerender.io with 127.0.0.1:3000 and since that is our service, we don’t must move any authentication headers.

The ensuing NGINX configuration file appears like this:

server {
    server_name shotquality.com;
    root /house/yasoob/shotqenterprise/REACT/construct;
    index index.html;

    location / {
  	    try_files $uri @prerender;
        add_header Cache-Management "no-cache";
    }

    location /static {
        expires 1y;
        add_header Cache-Management "public";
    }

    location /api {
        embody proxy_params;
        proxy_pass http://localhost:5000;
    }

    location @prerender {
        set $prerender 0;
        if ($http_user_agent ~* "googlebot|bingbot|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora hyperlink preview|showyoubot|outbrain|pinterest/0.|pinterestbot|slackbot|vkShare|W3C_Validator|whatsapp") {
            set $prerender 1;
        }
        if ($args ~ "_escaped_fragment_") {
            set $prerender 1;
        }
        if ($http_user_agent ~ "Prerender") {
            set $prerender 0;
        }
        if ($uri ~* ".(js|css|xml|much 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|svg|eot)") {
            set $prerender 0;
        }

        if ($prerender = 1) {
            set $prerender "127.0.0.1:3000";
            rewrite .* /$scheme://$host$request_uri? break;
            proxy_pass http://$prerender;
        }
        if ($prerender = 0) {
            rewrite .* /index.html break;
        }
    }
}

I eliminated the SSL help and redirection from this configuration file for the sake of simplicity.

Testing NGINX configuration

So as to take a look at whether or not our NGINX config adjustments didn’t break something, we will run:

$ sudo nginx -t

If all the things appears appropriate, we will restart NGINX:

$ sudo service nginx restart

To check whether or not our service is working the best way it’s speculated to, we will run the next CURL command:

$ curl -A googlebot https://instance.com

Exchange instance.com along with your React-based app URL and see if the output of this command is completely different from in the event you run curl with out -A googlebot.

You probably have reached this step then likelihood is that your prerender service is working effective. In case there are errors, please write about them within the feedback beneath and I’ll attempt to assist.

You all have a beautiful day and a satisfying new yr 🙂

Additional research:

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments