SRA - Single Page React App - when hosted to GitHub, doesn't load Component which stores 'switch' router code

Viewed 618

I have searched everywhere for the answer to this one - and I'm pretty sure it's the way I've laid out my Components in my React app:

In making my Portfolio page in React, I used CREATE REACT APP and after it was finished and functioning perfectly locally, I made the necessary changes to the package.json file for homepage and build, etc. Then when I deployed using Yarn, the host link would open my site - but without one of my components: CONTENT. This component contains a switch that, according to the route, will show the proper content in the body of the page containing that route.

When I click on the navbar, it will then take me to any of the three routes - including a properly displayed home page - but the home will only show after the page first loads and you click on the Navbar.

Why is this? Again - it works locally just fine, but on GH Pages, will only show the Header, NavBar and Footer for the home page on first load.

Thanks,

Rideout

See code below:

Hosted URL on GH Pages:

https://operasinger.github.io/VRideout-Portfolio-React/

Partial Package.json:

"homepage": "http://operasinger.github.io/VRideout-Portfolio-React/",
  "name": "vrideout-portfolio-react",
  "scripts": {
    "predeploy": "yarn run build",
    "deploy": "gh-pages -d build"
  },

App.js:

import React, { Component } from "react";
// import { Link } from "react-router-dom";
// import './Fonts.css';
import "./App.css";
import "bootstrap/dist/css/bootstrap.min.css";
import Navbar from "./components/navbar";
import Content from "./components/content";

class App extends Component {
  render() {
    return (
      <div className="App container-fluid" id="background">
        <div className="container">
          <div className="row jumbotronNavy">
            <div className="col-md-4 blue" id="headBlue">
              <h1>Vale Rideout</h1>
            </div>
            <div className="col-md-4 blue" />
            <div className="col-md-4 blue">
              <Navbar />
            </div>
          </div>
          <div className="row" id="content">
            <Content />
          </div>
          <div className="row justify-content-md-center" id="jumbotronFooter">
            <p>&copy; 2018 vale rideout</p>
          </div>
        </div>
      </div>
      // </div>
    );
  }
}

export default App;

Content Component:

import React from "react";
import { Switch, Route, BrowserRouter } from "react-router-dom";
import About from "./about";
import Projects from "./projects";
import Contact from "./contact";

const Content = () => {
  return (
    <BrowserRouter>
      <Switch>
        <Route exact path="/" component={About} />
        <Route path="/projects" component={Projects} />
        <Route path="/contact" component={Contact} />
      </Switch>
    </BrowserRouter>
  );
};

export default Content;

This is the home page when visiting the hosted GH Pages URL

When refreshed within GH Pages, the full route renders

I'm sure this is a very small problem, but it will help me with deploying React apps - as I'm sure it's not a problem native to React.

Thanks!

Rideout

3 Answers

The BrowserRouter component matches the entire URL as seen in the browser to your Routes. Since the root of your React implementation is not the base (/) of the domain, you should add a baseUrl property to your BrowserRouter to reflect that fact. I think you can do:

<BrowserRouter baseUrl="/VRideout-Portfolio-React"> but if not just look on the react-router docs.

If you'd prefer not to hard-code the path into the Router, you should be able to set a homepage inside package.json. Putting this in the package: "homepage": "https://operasinger.github.io/VRideout-Portfolio-React/" will prefix the paths with /VRideout-Portfolio-React when you run npm run build

Actually create-react-app docs covers this pretty well.

I've also noticed, that you are using Router component (BrowserRouter in your example) incorrectly. It should be above all of Routing configuration and Links in jsx tree. This is done to inject context, which will be used by all children of the Router component (even deeply nested).


TL;DR

Just use <HashRouter> as the root component of your Application.

Related