React Serverside rendering : build slicker apps with better SEO ranking
Here at the Telegraph Engineering, we use ReactJS for My Telegraph and TV Listings. We had the opportunity to rewrite our TV listings page, which used to be served by a PHP server. It had a great SEO ranking and one of our key objectives was to maintain and possibly improve it . In this blog I will discuss our journey from start to finish and show you how to set up a React Server Side rendered application.
Which Framework?
There are many great Frameworks and libraries available and each one has its pros and cons — we looked into a few of the leading ones in detail and composed a list of benefits — but we ultimately decided to use React. Below are some of the things we loved about it:
- Performant — uses a Virtual DOM to optimise rendering, which produces a slick and responsive UI.
- Reusable — it uses the component-based paradigm that highly encourages reusability.
- Testable — you can easily test each component in isolation and there are some great tools that help (we used Enzyme and Jest).
- Great ecosystem — there are many tools and libraries created by the community, tons of questions and answers and lots of blogs and tutorials.
- Developer experience — The React Dev tools makes debugging a charm.
- Readable — Components are readable and most of time are self explanatory.
- Excellent documentation — React has some great documentation which makes working with it great.
React and SEO
React runs on the client side which means when a user visits a react page the server sends a bare minimum HTML, most of the time its an empty div with an id — this then gets transformed by the JS — although this is done super quick and pretty much unnoticeable to the user it poses SEO problems- SEO bots usually don’t run any JS (pretty sure this will change in the future) so when they hit a site that uses React all they will receive is a HTML file like the one below — this is not good if you want your site to be ranked well.
<!DOCTYPE html>
<head>
<title>My React App</title>
<link rel="stylesheet" href="/styles.css" />
</head>
<body>
<div id="root"></div>
</body>
<script src="/bundle.js"></script>
</html>The solution
The solution was a simple one — we would create a node server which dynamically pre-renders the React application on the server side and sends the generated static HTML file to the client, thus SEO bots will receive content that can be ranked.
Before we begin
Before you start you will need to be familiar with the following:
- ReactJS
- NodeJS and how to install node packages
- ES6
- ExpressJS ( Web framework )
Lets Go
Assuming you have a React application already which you want to add server side rendering to..
- Create a new node project
- Install
react,expressandreact-dompackages.
npm install react express react-dom --save- Create
server.jsfile and setup server and route usingexpress
import express from 'express'const app = express()app.get('/', (req, res) => res.send('Hello World!'))app.listen(3000, () => console.log('app listening on port 3000'))
- You can run this file by running
node server.jsand test the server is up and running by using a browser to hitlocalhost:3000 - Now we will create a
template.jsfile which will be used to dynamically create anindex.htmlfile to serve ( you can use any templating language you like e.g Jade , we will use Vanilla JS in this tutorial)
export default ({ body, title }) => {
return `
<!DOCTYPE html>
<head>
<title>${title}</title>
<link rel="stylesheet" href="/styles.css" />
</head>
<body>
<div id="root">${body}</div>
</body>
<script src="/bundle.js"></script>
</html>`
;};As you can see, it’s just a function which takes in two params body and title and returns a string which will be our HTML.
- Now comes the magic; we will use the
renderToString()function fromreact-dom— this function takes in a React component and returns the html generated by this component — import your root React element in yourserver.js— so your file should look like this:
import express from 'express'
import { renderToString } from 'react-dom/server'/* Below is where we import our React application*/
import App from '../react-project/app.js';const app = express()app.get('/', (req, res) =>
res.send(template({
title: "Our App" ,
body: renderToString(<App/>)
}))
)app.listen(3000, () => console.log('app listening on port 3000'))
The final change we will need to make is to our client-side JS — you are probably using ReactDOM.render to render your application — All we need to do is use ReactDOM.hydrate() instead — what this does is instead of rendering your application from scratch it takes the current HTML and just ingests it to the React engine.
import React from 'react';
import { hydrate } from 'react-dom';hydrate( <App />, document.getElementById('root'));
Result
We were able to run our application through some SEO optimisation tools, which gave us some pointers on ways to increase our score, after implementing the changes we were able to improve our overall score and take us up the Google search rankings from 3rd to 2nd when you search for TV Listings, give it a go ! :D
If you have any questions or anything you would like to say in response to this blog please comment and I will try my best to respond.
Mustafa J is a frontend software engineer for The Telegraph.
