Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS server side rendering fo single page application

What I've already done

  • I have a frontend entirely built with React.JS.
  • All the business logic is handled by Django and exposed by Django REST Framework via an API.
  • I'm able to build for different mobile environnements (Android and iOS via Cordova)
  • The web application is accessible via my Django project (the same that exposes the api), the frontend is sill the same ReactJS code bundled via webpack.
  • The App has a single entry point, main.js which is a bundled version of my react.js components and dependencies, so my index.html typically looks like this :

    <body>
        <script type="text/javascript" src="/static/bundles/main-3997ad3476694c3c91cf.js"></script>
    </body>
    

What I want to do

  • I want to provide a server-side rendering of my web application to let web crawlers correctly index my app on web (I'm not looking for server-side rendering for mobile builds)

How can I handle this considering the fact that my app is a Single Page Application ? I do not want to reinvent the wheel nor to duplicate my code. What kind of node.js server do I have to write in order to achieve this automatic server-side rendering ? Is there any way to provide the server side rendering directly in Django (via some tools reading and interpreting the final results of the page as displayed on the client-side and returning this raw html ?)

like image 540
Pierre Criulanscy Avatar asked Jul 30 '15 15:07

Pierre Criulanscy


People also ask

Is server-side rendering single page application?

​ Server-side rendering, also known as universal or isomorphic rendering, is an alternative rendering method for single-page applications. SSR generates the static HTML markup on the server so that the browser gets a fully rendered HTML page. This is done by using a backend runtime such as Node.

Can Reactjs be a server-side rendering application?

Yes! This is where server-side rendering for React comes in. In this article, I want to introduce you to server-side rending (SSR) with React, reasons to use it, and some popular frameworks for rendering React on the server side.

Is React good for single page application?

React is great for single page applications because it allows developers to create applications that are mobile first and responsive. React allows developers to create applications that are fast and easy to update, which is great for mobile applications.

Is Reactjs rendered server-side or client-side?

js is used for server side rendering of react application . React along with other framework like angular and vue. js are traditional client side framework ,they run in browser but there are technology to run this framework on server side, and next.


1 Answers

You have probably solved your problem by now, but I wanted to share my solution for this.

I have a very similar setup, and have something that seems to work pretty well so far. I basically have a django w/ DRF backend api and isomorphic React/Flux javascript app. I also run a node server next to the python backend server, which acts only as a 'template rendering' service. In essence, replacing the django render function.

So I simply replace the django View with a special IsoView which calls off via http to the node server and returns the rendered html.

from rest_framework.renderers import JSONRenderer
import requests

class IsoView(View):

    def user_json(self):
        if self.request.user.is_anonymous():
            return {'anonymous': True}
        else:
            return UserSerializer(self.request.user, context={'request': self.request}).data

    @classmethod
    def render(cls, request, template, data):
        req_data = JSONRenderer().render(data)
        try:
            headers = {'content-type': 'application/json'}
            query_params = request.GET
            resp = requests.post(_build_url(request.path), params=query_params, data=req_data, headers=headers, timeout=0.1)
            reply = resp.json()

            if resp.status_code == 302:
                return redirect(reply.get('redirect'))

            if 'error' in reply:
                raise Exception("\n\nRemote traceback: {}".format(reply.get('traceback')))

        except requests.exceptions.RequestException as err:
            logger.warn('IsoView request exception: {}'.format(err))
            reply = {}

        return render(request, template, {
            'react': reply.get('result'),
            'data': data
        })

And use it like so:

class HomePage(IsoView):

    def get(self, request, *args, **kwargs):
        return self.render(request, 'app.html', {
            'user': json_data...
        })

This also assumes a django template which uses something like this

<html>
<head>
    <script>
        window.data = {{ data|json }};
    </script>
</head>
<body>{{ react|safe }}</body>
</html>

What this does is it renders the html returned from node in the body tag and also dumps the json data required for bootstrapping the app on the client in the window.data object.

This is a really simplified version of the system, but it should work. You should be careful with XSS attacks on the window.data bit, so make sure to escape all your json data but other than that, you should be all good.

Then the node template server looks really similar to any of the tutorials online that you can find for server-side react. Just a simple express app.

Alternatively, you don't need to mess around with django templates at all if you render the full ... in node and return that as a string.

Hope that helps.

like image 81
Peter Matev Avatar answered Sep 28 '22 11:09

Peter Matev