How to add SSR to a CRA

By Jean Bauer

21 December 2018

Oh God, I feel so millennial with this title, oh wait

This article is heavily inspired by this one. The idea behind creating a new tutorial is to explain step by step, error by error. If you wanna a more quick/intermediate tutorial, I highly recommend going directly here.

Alright then. Firstly, what is SSR and why would someone want to add that to a Create React App.

SSR: Server side rendering is a good way to delivery HTML faster to ur clients and also have good SEO.

CRA: Create react app is a tool to create react apps without wasting time configuring stuff.

npx create-react-app my-app

Ok, now you should have your CRA up and running, it's time to add SSR to it, so as obvious as it seems we need a server in our application (you didn't see that coming huh?)

yarn add express

In order to use express we need to import it into a file, go on and create a server.js.

The content of the server should be something like:

import express from 'express'
import serverRenderer from './serverRenderer'

const PORT = 3000
const path = require('path')

const app = express()
const router = express.Router()

router.use('*', serverRenderer)
router.use(express.static(path.resolve(__dirname, '..', 'build')))

app.use(router)
app.listen(PORT, () => console.log(`listening on: ${PORT}`))

Also you need to create the serverRenderer file which you can find here.

Alright, lastly, create a parser.js file so Node can know how to read JSX that will look like this:

require('@babel/register')({
    ignore: [ /(node_modules)/ ],
    presets: [
        '@babel/preset-env',
        '@babel/preset-react',
    ],
})

require('./server')

We are all set, if we run:

node parser.js

We should see an error like this:

(function (exports, require, module, __filename, __dirname) { <svg xmlns=”http://www.w3.org/2000/svg" viewBox=”0 0 841.9 595.3">
 ^ SyntaxError: Unexpected token <

To fix that, import ignore-styles hook to the server.js.

require('ignore-styles')
require('@babel/register')({
    ignore: [ /(node_modules)/ ],
    presets: [
        '@babel/preset-env',
        '@babel/preset-react',
    ],
})

require('./server')

now if you run yarn build and then node server.js you should be able to see your app running on your http://localhost:3000/

That's it. If you wanna dig little further check this article with redux/helmet/etc.