Most beginner personal web development projects start with using create-react-app. create-react-app is a simple react-based application, prominently used by newcomers as a tutorial. However, it does not lower its quality as a production-ready framework. Coupled with other packages and plugins found in npm registry, we can create a professional website in no time.
Using create-react-app with react-router allows creating routes for our React.js application. This blog will focus on SSR with code bundling to improve performance. Furthermore, we will deploy to Heroku using the production build from npm run build
, which acts as a static site rather than dynamic site (npm start
).
tl;dr
- Read this example on how to enable Server Side Rendering through React Router
- Install serve (
npm i serve
) for serving built static web - Update the Heroku Procfile to
web: serve -s build
1. create-react-app with react-router
react-router enables create-react-app application to use routing, primarily Client Side Routing (CSR). However, in this post, we are only going to use react-router for its Server Side Routing (SSR).
A little note about CSR vs SSR
In shorthand, in Server Side Routing (SSR), the user requests a whole new page, while in Client Side Routing (CSR), the user only request changes in data and the page changes accordingly. So, SSR requires the user to download more data (and thus slower) compared to CSR.
react-router focuses on CSR, but we can use it as SSR as well. You can find the tutorial for this in their website (SSR up until Nested Routes section).
SSR through Code Bundling
CSR might have slower initial load since the user needs to download all data, even the ones that they never going to see. Let's say there are 3 routes: /home
, /about
, and /user
. If we use react-router as it is from the tutorial, then the user will download all content in those three pages, although they only open one of the page. Code bundling will solve this issue. Refer this legacy docs for how to implement code bundling.
2. How Heroku Runs create-react-app
This is how Heroku runs create-react-app on default (applies to with or without react-router).
- Heroku automatically detects that the app is a Node.js app
- Heroku runs
npm install
, followed bynpm run build
if it is defined in package.json. create-react-app already definednpm run build
. - Heroku looks for Procfile file and all defined processes. Usually this file only contains a single line:
web: npm start
. - Heroku will run their dynos (server) based on one of these processes.
However, this is not optimized since we are using the development build. Heroku did build the production build, but they still use the development build (note the web: npm start
command in Procfile).
Run the Production Build (Static Site) Locally
Using npm start
, the website will be run as a dynamic site. If your website has no dynamic or back-end code, then we can build it to be a static website.
First, we need to build the app first by running npm run build
. It will create a new directory called build
which contains static HTML, CSS, JavaScript, public files, etc. We can not just open the index.html
file and expect it to work. We need to run a static server.
There are many different ways to run a static server. In Node.js, you can install packages like
http-server
,static-server
, andserve
. In Python, you can usehttp.server
.
We are going to use serve as it is fast and simple to use.
npm install serve
serve -s build
3. Run the Production Build (Static Site) on Heroku
Heroku automatically runs npm run build
, but it still run the application using npm start
, which is not optimized. We can use serve
to run the production build (static site).
Add this dependency in package.json (or just run npm install serve
if you're not sure about the version).
"serve": "^14.2.0",
Update the Procfile.
web: serve -s build
That's It
And those are the reasons behind why I did those steps to run create-react-app
with react-router
on Heroku.
Alternative without serve
(Using Express)
Instead of installing serve
or other static site server, we can create a server.js file in the root directory.
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) { // marked
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(9000);
If you use react-router, then change the marked line to app.get('/*', function(req, res)) {
.
Also don't forget to update the Procfile.
web: node server.js
And that's it! Now Heroku will run the production build without installing serve
or any other application.
Top comments (0)