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.
Installation
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';render((
<BrowserRouter history={ browserHistory }>
<App />
</BrowserRouter>
), 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) => (
<Switch>
<Route exact path="/" component={ Landing } />
<Route component={ Error404 } />
</Switch>
);
So, with those routes defined, whenever a user goes to http://mydomain.com/
, the Landing
component will be rendered. If they try to go to http://mydomain.com/aboutus
, the Error404
component will be rendered because that route is not defined.
App.js
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:
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.
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.
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!