Reach router not working on refresh on gh-pages

1.7k Views Asked by At

I have a personal website hosted on gh-pages, and have deployed it etc, and all seemed to be working fine. However I noticed that the router works on the homepage and also when clicking the links to the other pages, however when I refresh on a url or type it in manually, it doesn't work.

I am using React with reach-router. I have tried using process.env.PUBLIC_URL with all my links and paths. However this doesn't fix the issue.

My routing is as follows:

import React, { Component } from 'react';
import { Router } from "@reach/router";
import Home from './containers/Home';
import About from './containers/About';
import './scss/main.scss'
import Nav from './components/Nav';
import Work from './containers/Work';
import Footer from './components/Footer';

class App extends Component {
    render() {
        return (
            <div>
                <Nav/>
                <main className="wrapper">
                    <Router>
                        <Home path="/"/>
                        <About path="/about"/>
                        <Work path="/work"/>
                    </Router>
                </main>
                <Footer/>
            </div>
        );
    }
}

export default App;

When I had this problem locally, I fixed it by doing

devServer: {
    historyApiFallback: true,
    contentBase: path.join(__dirname, 'public'),
    port: 9000
},

however, as this in is prod on gh-pages, I am not sure if there is an equivalent!

Does anyone have any ideas? I've spent days wondering about this, and asked several other devs who can't work it out either!

Thanks in advance!

2

There are 2 best solutions below

1
On

So as it turned out, I figured this one out with a lot of help from google. Leaving this here for anyone who needs it!

I used this package https://www.npmjs.com/package/hash-source

Then did this:

import React, { Component } from 'react';
import Home from './containers/Home';
import About from './containers/About';
import './scss/main.scss'
import Nav from './components/Nav';
import Work from './containers/Work';
import Footer from './components/Footer';
import {
    createHistory,
    LocationProvider,
    Router
  } from "@reach/router";
  import createHashSource from 'hash-source'

  let source = createHashSource();
  let history = createHistory(source)

class App extends Component {
    render() {
        return (
            <LocationProvider history={history}>
                <div>
                    <Nav/>
                    <main className="wrapper">
                        <Router>
                            <Home path="/"/>
                            <About path="/about"/>
                            <Work path="/work"/>
                        </Router>
                    </main>
                    <Footer/>
                </div>
            </LocationProvider>
        );
    }
}

export default App;

Basically it seems gh-pages can't use the normal HTML5 push history situation, so we have to use hash history. Since reach-router doesn't support this, someone kindly made an extra library for it, and voila, it works! Thanks to that person!

0
On

It took me a while to figure out (regarding that I have <Router basename={process.env.PUBLIC_URL}>) What worked for me is adding these to package.json

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

It fixed crashes on gh-pages refresh