Lessons

Hosting a React App for Free using Github Pages

In this tutorial, I walk you through setting up a simple React.js application that can be hosted on Github Pages. I really like hosting here because it's free for me personally, and Github handles "server management". Once I deploy my React app and verify it's up, Github handles the traffic surges, updates, etc.

I typically use this MERN boilerplate repository repository but it has too much extra stuff specifically for a Node server. I found this repository. It's a much simpler boilerplate code base and only focuses on React. Please star, my fork so I know people are still using it. I also recommend copy the files into your repository.

Initial

The first step is verifying we have a full project and it can be run. I am assuming you have Node.js on your computer and that the environment has been used before. If not, just go to the Node.js website and download it. For me (you can be on a different version, but try to be at least later):

1 node --version
1 v10.16.1

I copied my files over to a new empty repository so I'm first going to commit them up. GH-Pages is the npm package under the hood shipping to the build to Github Pages. GH-Pages pulls from master.

1 2 3 git add --all git commit -m "The start of my website" git push origin master

Screenshot of Github Workflow Running

The next step is to run it locally. We need to install all dependencies with:

1 npm install

And we can run it locally on our computer using:

1 npm run start

It will either open a browser or you can open http://localhost:3000.

Screenshot of Github Workflow Running

Screenshot of Github Workflow Running

Our app is running and we have our environment setup.

Shipping to GH-Pages

Now, we will send this very simple app to GH-Pages. Run:

1 npm run deploy

Screenshot of Github Workflow Running

You can find more information about your app under the Github repository settings.

Screenshot of Github Workflow Running

CNAME

As you can probably see, there is a way to add a custom domain to a project. Skip this if you do not have one. You want to create a file called CNAME in the route of the project. Put just the domain name without http and https. For me it's:

1 keithweaver.ca

Head over to the Github Pages settings in the settings tab. For the first time add it there too. You may need to verify domain ownership. You should also force HTTPS. On your DNS Record, you just need to add the following records:

1 2 3 4 5 Type Name Value TTL Actions A @ 185.199.108.153 600 seconds A @ 185.199.109.153 600 seconds A @ 185.199.110.153 600 seconds A @ 185.199.111.153 600 seconds

I had one issue with this code when using the CNAME. Every time I would deploy it would remove the CNAME. I added the following to my package.json. I had this in scripts:

1 "predeploy": "npm run build",

And I changed it to:

1 "predeploy": "npm run build && cp CNAME build/CNAME",

This will move the CNAME file into the build. This solves the issue.

Multiple Routes

I am going to switch to local development again, but the same applies when you do a deploy to Github Pages. The other aspect that does not work out of the box is React Router for handling multiple routes.

We will setup the application to handle multiple routes. The first is moving files:

1 2 3 4 5 6 7 8 9 10 public/ src/ containers/ App/ App.js Home/ Home.js HelloWorld/ HelloWorld.js index.js

I have remove a few files that are not required for this lesson. I've moved App.js into multiple subdirectories.

Changed index.js to be:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import React from 'react'; import ReactDOM from 'react-dom'; import { Route, Switch } from 'react-router'; import { BrowserRouter } from 'react-router-dom'; import App from './containers/App/App'; import Home from './containers/Home/Home'; import HelloWorld from './containers/HelloWorld/HelloWorld'; import registerServiceWorker from './registerServiceWorker'; ReactDOM.render(( BrowserRouter> App> Switch> Route exact path="/" component={Home} /> Route path="/hello" component={HelloWorld} /> /Switch> /App> /BrowserRouter> ), document.getElementById('root')); registerServiceWorker();

Changed App.js to be:

1 2 3 4 5 6 7 8 9 import React from 'react'; const App = ({ children }) => ( div> {children} /div> ); export default App;

Add Home.js to be:

1 2 3 4 5 6 7 8 9 import React from 'react'; const Home = () => ( div> p>Home/p> /div> ); export default Home;

Add HelloWorld.js to be:

1 2 3 4 5 6 7 8 9 import React from 'react'; const HelloWorld = () => ( div> p>Hello World/p> /div> ); export default HelloWorld;

We are missing a few packages. We need the React Router. Run:

1 2 npm install react-router --save npm install react-router-dom --save

Now you can test it with:

1 npm run start

Screenshot of Github Workflow Running

Screenshot of Github Workflow Running

Both routes worked. If this fails on the Github pages, you can add the following (I did it for my site):

1 "build": "react-scripts build && cp build/index.html build/404.html",

Conclusion

Github Pages is a fantastic way to host web pages. Now you are able to do it very easily using React.

Thanks for reading!