Server-side React Rendering From non-Node Environments

Written by musawiralishah | Published 2017/03/22
Tech Story Tags: react | javascript | golang | server-side-rendering | nodejs

TLDRvia the TL;DR App

If most of your front-end is built using React components, it makes sense to use the same code to render your views from the backend. This pre-rendering, i.e. not waiting for your Javascript to load in the web browser before components get rendered, is particularly important for SEO. Luckily, React provides functionality to render components into an HTML string, which can then be returned from the web server. However, React is a Javascript library, and therefore a Javascript runtime environment is required. If you’re using NodeJS for your backend, you’re good to go. But if you use Ruby on Rails, Go, Django, or any other non-Javascript environment, you won’t be able to use React’s server-side rendering functions directly.

Enter preact-rpc.

Preact-rpc is three things packaged into one:

  1. An RPC server that fulfills React component rendering requests by clients connected to it.
  2. A library to register React components in your Javascript bundle so that the RPC server can find them.
  3. A collection of language specific libraries to connect with the RPC server and send render requests to it.

The basic idea is this. Run a NodeJS socket server that can render React components on behalf of clients and return the HTML string. This method is pretty efficient because the server loads the Javascript bundle containing the components at start and keeps it in memory.

The overall system is quite simple, but lets walk through an example to make things crystal clear.

Assume that our backend is a Go app, and we would like to render React components from there. Lets say we have a simple component like this:

It is a simple component that takes a prop toWhat and prints out a Hello message.

Now lets install the module: npm install preact-rpc

Next, we need to register our components so that our RPC server knows how to identify a particular React component given some sort of ID/name. To do this, we modify our Javascript as follows:

We’ve registered the component Hello with the name ‘hello’. We’ll use this name when we want to send render requests later.

Even though I’ve only used a single component in the example above, you can register as many components as you need. In practice, you’d create a Webpack bundle that includes all the required components.

Your Javascript is now ready. We can now start the RPC server with this Javascript file:

This will start a server with a UNIX socket. You can use a TCP socket by providing a number for the port command line argument.

After the server starts, it is ready to fulfill component rendering requests. The protocol is very simple. The request is in the form of JSON:

The server expects requests to end in a special sequence of bytes. By default this is defined as: \r\n.

We can now write a client to connect to the server in the language of our choice. You can write this code yourself if you wish, or you could use one of the helper libraries included with preact-rpc. For Go, the package github.com/musawirali/preact-rpc/goclient is included. Here is our Go backend that uses this package to connect to the RPC server started earlier:

Run the app and see our simple Hello component rendered.

In its current state, the preact-rpc package is functional, but still quite minimal. A number of things are in the pipeline to flesh out the system:

  • Seamless continuity of React component lifecycle from backend to front-end when the front-end Javascript is loaded.
  • Support for Redux stores.
  • Build out helper libraries for more languages/environments.

Hope this project is helpful to the community. Contributions are welcome!

Hacker Noon is how hackers start their afternoons. We’re a part of the @AMIfamily. We are now accepting submissions and happy to discuss advertising & sponsorship opportunities.

To learn more, read our about page, like/message us on Facebook, or simply, tweet/DM @HackerNoon.

If you enjoyed this story, we recommend reading our latest tech stories and trending tech stories. Until next time, don’t take the realities of the world for granted!


Published by HackerNoon on 2017/03/22