Click here to share this article on LinkedIn »

Think again! Nah… I’m just playing, it’s possible but it will definitely take some configuration to get your routes rendering the correct components.

GitHub has this feature called GitHub Pages that converts a GitHub repository into a living, breathing website with a click of the button… as long as this repo is a) written in Frontend code only(Javascript, CSS and HTML) and apparently b) not written in React. If you’ve recently finished a React single page application like me that employs a heavy use of React’s Router Dom library to render certain components when users navigate to certain URLs then this guide is for you.

Slight backstory (skip to the section entitled “Quick Guide for those that are pissed off and want to know the answers now!” for said answers): after a few days of head-banging sessions I finally had my backend hosted on Heroku. Things were looking up! Or so I thought 😠. When I tried to get my site up on GitHub Pages, which I have had some success at in the past (see my Trump-inspired Duolingo app here or my wave forecast site for the best dang city on the Jersey Shore aka Strathmere’s mobile friendly site), but because I used React to build this particular app I needed to add some extra lines of code to make sure GitHub could recognize my components based on what actions users took on my site.

Chylingo in all its glory. FYI: animations took me centuries (and they look weird in this GIF having just recorded it. Urg…)

Quick Guide for those that are pissed off and want to know the answers now!

So you have your React app built and it looks great on your local machine. Awesome! Now let’s get it online.

Make sure you have a remote GitHub repository attached to your local project. See their docs for instructions.

2. Run npm install

$ npm install

This makes sure you have the most recent version of npm and node.js installed. Even though I was running my backend with Rails I was getting strange errors without it.

3. Run npm run build

$ npm run build

This will create a bunch of Javascript, HTML and CSS files that GitHub will use to convert your project into a file structure GitHub Pages can handle.

Image from FreeCodeCamp, great resource for learning development. They also have an incredible podcast. Check them out.

You’ll see something like this ^.

4. Grab that whole “homepage” line and add it to your package.json

This line will link up the branch you are creating with the repo you would like to get live.

5. Run npm run build one more time.

$ npm run build

You’ll see the following code in the console changes a bit from last time. It now reads:

blah blah blah "scripts": {

//..

“deploy”: “gh-pages -d build”

}

You’re going to want to grab that line of code I bolded above and add it to your package.json file under the key “scripts”:

“scripts”: {

“start”: “react-scripts start”,

“build”: “react-scripts build”,

“test”: “react-scripts test — env=jsdom”,

“eject”: “react-scripts eject”,

“predeploy”: “npm run build”,

“deploy”: “gh-pages -d build”

} //bold means I added this line. Do it.

6. Run npm run deploy.

$ npm run deploy

This will not only use the GitHub gh-pages plugin to automatically push up your current repo to a new branch on your remote repo (or if you’ve run this command before will update files on that existing branch) under the guise of a new branch with the name ‘gh-pages’, but also automatically toggles your repo settings to turn on the GitHub Pages and sets the repo GitHub Pages will use to render your application to the ‘gh-pages’ branch, which converted all of your normal React javascript into code it can read.

Now time for the fun part. If you navigate to your GitHub pages site (the command npm run deploy will tell you where to navigate to see your successfully deployed site), what do you see? If you’re like me and did not set up a root route then you’ll see a 404 error.

7. Make a root route and add basename={process.env.PUBLIC_URL} as a prop to your BrowserRouter component.

Now this is where my panic set in because before adding this component to my BrowserRouter and reconfiguring my root route when I navigated to my repo GitHub Pages link nothing was showing up. After some sniffing around in the console I found a 404 error telling me that the component ‘Home’ could not be rendered. Why was my app working perfectly fine locally but not on a server? Enter the mysterious, ethereal process.env.PUBLIC_URL. If you console.log(“Your process.env.PUBLIC_URL”, process.env.PUBLIC_URL) and navigate to the correct GitHub Pages URL you’ll see “/yourreponame” in the console. A clue!

So I added the basename prop to my Router (aliased from BrowserRouter) in my index.js file:

import React from ‘react’;

import ReactDOM from ‘react-dom’;

import ‘./index.css’;

import App from ‘./App’;

import GameOver from ‘./components/GameOver’;

import StartGame from ‘./components/Home’;

import ‘semantic-ui-css/semantic.min.css’;

import { BrowserRouter as Router } from ‘react-router-dom’; ReactDOM.render(<Router basename={process.env.PUBLIC_URL}>< App /></Router>, document.getElementById(‘root’));

Then I navigated to my App.js file to change my root route, which originally looked like this:

import React from 'react';

import ReactDOM from 'react-dom';

import './index.css';

import App from './App';

import 'semantic-ui-css/semantic.min.css';

import { BrowserRouter as Router} from 'react-router-dom'; ReactDOM.render(<Router basename={process.env.PUBLIC_URL}>< App /></Router>, document.getElementById('root')); // I added the code basename={process.env.PUBLIC_URL} so that in my App.js file I could map my components to certain routes in my App render() function like so: render() {

console.log(this.state);

console.log("This is the process.env", process.env.PUBLIC_URL)

// debugger

return (

<div>

<Route exact path={`/gameover`} component={GameOver} />

<Route exact path={`/new`} render={ (routerProps) => < NewUser routerProps={routerProps} />} />

<Route exact path={`/edit`} render={ (routerProps) => < EditUser routerProps={routerProps} />} />

<Route exact path={`/home`} render={ (routerProps) => < Home routerProps={routerProps} setUpGame={this.setUpGame} />} />

<Route exact path={`/gametime`} render={ (routerProps) => < QuestionContainer user1Id={this.state.user1Id} user2Id={this.state.user2Id} gameId={this.state.gameId} routerProps={routerProps}/>} />

</div>

);

}

See the bold line above? This was really my landing page and what I wanted to display when a user navigated to my link. I had to change the path={‘home’} to {‘/’}. That means that when the Route’s path matched ‘process.env.PUBLIC_URL’ (reponame + ‘/’) it would render the Home component. When I changed that my landing page appeared!

<Route exact path={`/`} render={ (routerProps) => < Home routerProps={routerProps} setUpGame={this.setUpGame} />} />

Fantastic! My routes are set up correctly. Back to the process.env.PUBLIC_URL. Stack Overflow told me that process.env.PUBLIC_URL is a part of the node.js library and is a dynamically generated url that changes based on what development mode you are in, whether you are working on your app locally (in which case the process.env.PUBLIC_URL would most likely be http://localhost:3000/ or something to that effect), or on an actual production server like GitHub pages (http://bmcilhenny.github.io/trivia-front-end).

Which brings me to my next section in this longwinded blog:

Takeaways from my bloody battle with GitHub Pages

GitHub Pages is not smart enough to use React’s Route component out of the box. With some slight configuration and a few hours staring at various forums and docs I finally got my routes working and rendering the correct components, although for some reason when I manually navigated to certain URLS like “https://bmcilhenny.github.io/trivia-front-end/edit” I stumbled into a 404 error. I could reach this route via my Nav bar on my home page but after I refreshed GitHub was still spewing out a 404 error. It took me another hour to realize that this is GitHub’s issue, not mine. Due to the way GitHub converts your React app into a GitHub-like repo it always looks to the index.html file to render. So you need to add a script to your index.html file to hackily redirect from the index.html file to the correct component. If you are using the Link component from the react-router-dom library and want to link back to your landing page (for a “Back to Home” button perhaps), I tried these options with no success:

//1. I tried: <Menu.Item as={Link} to={process.env.PUBLIC_URL} >

//2. and this: <Menu.Item as ={Link} to=”/” > to no avail.

It was not until I pointed the Link to=”” that it actually rendered the right component, which does not make sense to me but hey, sometimes that’s how programming goes.

After what feels like a century of banging my head against the hardest and roughest of brick walls I was finally able to get my frontend React app hosted on GitHub Pages, or so I thought.

Handling Hard Refreshes on Routes that are not your Root Route

As how most things work out in life, it was not until I fixed the issue with little direction that I saw that as part of the files that comes baked into a React app is the README.md which reads:

#### Notes on client-side routing GitHub Pages doesn’t support routers that use the HTML5 `pushState` history API under the hood (for example, React Router using `browserHistory`). This is because when there is a fresh page load for a url like ` http://user.github.io/todomvc/todos/42` , where `/todos/42` is a frontend route, the GitHub Pages server returns 404 because it knows nothing of `/todos/42`. If you want to add a router to a project hosted on GitHub Pages, here are a couple of solutions:

* Alternatively, you can use a trick to teach GitHub Pages to handle 404 by redirecting to your `index.html` page with a special redirect parameter. You would need to add a `404.html` file with the redirection code to the `build` folder before deploying your project, and you’ll need to add code handling the redirect parameter to `index.html`. You can find a detailed explanation of this technique [in this guide]( * You could switch from using HTML5 history API to routing with hashes. If you use React Router, you can switch to `hashHistory` for this effect, but the URL will be longer and more verbose (for example, ` http://user.github.io/todomvc/#/todos/42?_k=yknaj` ). [Read more]( https://reacttraining.com/react-router/web/api/Router ) about different history implementations in React Router.* Alternatively, you can use a trick to teach GitHub Pages to handle 404 by redirecting to your `index.html` page with a special redirect parameter. You would need to add a `404.html` file with the redirection code to the `build` folder before deploying your project, and you’ll need to add code handling the redirect parameter to `index.html`. You can find a detailed explanation of this technique [in this guide]( https://github.com/rafrex/spa-github-pages ).

While you can push browserHistory to a route like “/” locally you lose access to browserHistory on GitHub. If you use browserHistory.push anywhere in your app you’re going to want to remove it and change it it to either a Redirect to=”route” or a Link to=”route”.

FOR YOUR INFORMATION: When you do a hard refresh when on a particular Router Route like “/newuser” you will see a 404 error. Because GitHub pages is only able to read one single page aka the index.html file it won’t know that “/newuser” exists. What React Router is actually doing is tricking your browser into thinking it’s at an actual new address when really all it is doing is changing the text inside the url, not the url location of the client. That’s why they recommend switching to hashHistory.

8.5 hours into the process and changing my routes again seemed like quite the undertaking given the circumstances so I took the hacky route instead. Some angel out there wrote 2 scripts that handle these hard refreshes so that your browser is automatically pushed back to the index.html file (aka your root route) if it encounters a 404 error then navigates to the correct “/route” that you called the hard refresh on.

Check out my finished project here. Shoutout to Josh Stillman for being the logical ninja partner that he is and teaming up with me to tackle this mountain in 4 days.

My parting message: this is definitely not the best approach for hosting your React app. It’s hacky at best and though I have not tried, I seriously doubt GitHub Pages will be able to handle user authentication but hey, the world works in mysterious ways.

You’ve made it this far? Much appreciated for reading! I am always looking for feedback on my blogs and projects. Don’t be afraid to leave a comment or send me a message. Also on the journey of transitioning to a career in Software Development? I’d love to connect on Linkedin.

Enjoy my writing? Check out my other articles👇 down below.