How to set up React Router and deploy to Amazon S3

Having the luxury to work at startups means not spending a lot of money on IT, so I looked at many different options for our hosting needs. I found S3 can host sites in buckets, so I tried it out. It has worked out pretty well so far.

I have had the chance to create web applications from scratch using React, Redux, Router, and whatnot. Since it was a bit unclear where to set up the initial routing for React, I want to document my experience to help others who stumble upon this same topic.


npm install react-router-dom --save

At the time of my installation, the version I got is 4.2.2. The React version we are using is 15.6.1.

Folder Structure

We use webpack for our development server, so we have an entry.js file as the entry point for our application. It was a simple file that contains some import statements and the line:

render(<App />, document.getElementById('root'));

So, let’s change it and add router to this file:

'use strict';
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter, browserHistory } from 'react-router-dom';
import App from './Components/App';
<BrowserRouter history={ browserHistory }>
<App />
), document.getElementById('root'));

The reason we chose to use BrowserRouter instead of HashRouter is we want a cleaner URL and we have a dynamic site that talks to our backend API.

Where are the routes?

Let’s create a file called routes.js that lives outside the Components folder, which will contain all our routes:

'use strict';
import React from 'react';
import { Route, Switch } from 'react-router-dom';
import Error404 from './Components/error404';
import Landing from './Components/landing';
export const routes = (props) => (
<Route exact path="/" component={ Landing } />
<Route component={ Error404 } />

So, with those routes defined, whenever a user goes to, the Landing component will be rendered. If they try to go to, the Error404 component will be rendered because that route is not defined.


Lastly, let’s add the routes into our App.js:

'use strict';
import React, { Component } from 'react';
import { routes } from '../routes';
class App extends Component {
render() {
return routes;
export default App;

That’s all there is to it in our code.

Webpack config to package files and router to work locally

To make the routers work locally, we need to add historyApiFallback: { index: ‘/' } to webpack.config.js.

So, our webpack.config.js ends up to be:

'use strict';
const htmlWebpackPlugin = require('html-webpack-plugin');
const htmlWebpackConfig = new htmlWebpackPlugin({
template: __dirname + '/src/index.html',
filename: 'index.html',
inject: 'body'
module.exports = {
entry: __dirname + 'src/entry.js',
output: {
path: __dirname + '/build',
filename: 'bundle.js'
module: {
loaders: [
test: /\.js?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: [ 'es2015', 'react' ]
plugins: [ htmlWebpackConfig ],
devServer: {
inline: true,
port: 8080,
historyApiFallback: {
index: '/'

Deploy to Amazon S3

Let’s package up our files by running webpack --progress --colors. After that is done, we have 2 files: bundle.js and index.html.

Go to Amazon S3 Management Console and create a bucket:

Amazon S3 Create Bucket

After supplying the bucket name and click theCreate button, we have a bucket. Click the Upload button to upload the bundle.js and index.html files to the bucket.

Upload to S3 Bucket

After the files are uploaded, go to the Properties tab and click the Static website hosting option. Choose the “Use this bucket to host a website” option and supply index.html to both the “Index document” and “Error document” fields.

Static website hosting on S3

After clicking the Save button, we go to the endpoint listed on the Static website hosting dialog box to test our routes.

We are very happy that we can host our site on S3. We don’t even need to spin up an EC2 instance! We save cost. Hope this helps with hosting your site as well!