1

I am trying to deploy my Full Stack React Application to Heroku but I am unable to load up other routes of my application.

My App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

// Pages
// =================

// Not Logged In
import SplashPage from './Pages/SplashPage';
import Login from './Pages/Login';
import Signup from './Pages/Signup';
import CohortSignup from './Pages/CohortSignup';

// Logged In 
import AdminHome from './Pages/AdminHome';
import InstructorHome from './Pages/InstructorHome';
import StudentHome from './Pages/StudentHome';
import Settings from './Pages/Settings';

import StudentProfile from './Components/StudentProfile';

// No Page
import NoPage from './Pages/NoPage';

// Components
import Navbar from './Components/Navbar';

// Utils
import API from './Utils/API';

class App extends Component {
  state = {
    // We want to change this state based on User Login Credentials
    user: '',
    userType: '',
    loggedIn: false
  }

   // class functions go here

  render() {

    // If the user state login is true, allow them to navigate these pages
    if (this.state.loggedIn === true) {
      return (
        <Router>
          <Navbar user={this.state.user} logout={this.logout} />
          <Switch>
            {this.state.userType === 'administrator' ? <Route path='/' exact component={() => <AdminHome user={this.state.user} />} /> : ''}
            {this.state.userType === 'instructor' ? <Route path='/' exact component={() => <InstructorHome user={this.state.user} />} /> : ''}

            {/* Path for student profile based on it */}
            <Route exact path='/student/:id' exact component={StudentProfile} />

            {this.state.userType === 'student' ? <Route path='/' exact component={() => <StudentHome user={this.state.user} />} /> : ''}
            <Route exact path='/settings' exact component={() => <Settings user={this.state.user} />} />
            <Route component={NoPage} />
          </Switch>
        </Router>
      )
    } else {
      return (
        <Router>
          <Switch>
            <Route exact path='/' exact component={SplashPage} />
            <Route exact path='/login' exact component={Login} />
            <Route exact path='/signup' exact component={Signup} />

            {/* Go to signup based on cohortID */}
            <Route exact path='/signup/:id' exact component={CohortSignup} />

            <Route component={NoPage} />

          </Switch>
        </Router>
      )
    }
  }
}

export default App;

server.js

// Allows us to place keys and sensitive info in hidden .env file
require("dotenv").config();

// Require Packages
const express = require("express");
const app = express();
const db = require("./models");
const routes = require("./routes");
const passport = require("passport");
const session = require("express-session")
const path = require("path");

const MySQLStore = require("express-mysql-session")(session);

require("./config/passport")(passport)
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

let options = {};
if (process.env.NODE_ENV === 'production') {
    app.use(express.static("client/build"))
    options = {
        host: process.env.HOST,
        port: 3306,
        user: process.env.USER,
        password: process.env.PASSWORD,
        database: process.env.DB
    }
} else {
    options = {
        host: 'localhost',
        port: 3306,
        user: 'root',
        password: process.env.DB_PASSWORD,
        database: 'tracker'
    }
}


// Options for mysql session store

let sessionStore = new MySQLStore(options);

// Pass in mysql session store
app.use(session({
    key: 'surfing_dogs',
    secret: 'surfing_dogs',
    store: sessionStore,
    resave: false,
    saveUninitialized: false
}))

app.use(passport.initialize());
app.use(passport.session());

app.use(express.static(__dirname));
// app.use(express.static(path.join(__dirname, 'build')));

app.use(routes)


app.get('/*', function (req, res) {
    res.sendFile(path.join(__dirname, 'build', 'index.html'));
    // res.sendFile(path.resolve(__dirname + '/client/build/index.html'));
});


db.sequelize.sync({ force: false }).then(() => {
    let server = app.listen(process.env.PORT || 5000, function () {
        let port = server.address().port;
        console.log(`Server is listening on PORT ${port}`)
    })
})

Here is the site link

The initial root page loads up fine but when I try to access the /login or /signup route directly from the address bar it does not work

Here is a link to the Github Repository

I have also looked at other Stack Overflow answers for my problem to no avail.

React Routing works in local machine but not Heroku React Router Routes Don't work when deployed to Heroku

The solutions in these suggest that I add a static.json and have an app.get() method that will redirect any route to my index.html due to react being a single page application. If anyone could guide me in the right direction I would be grateful!

pythonNovice
  • 1,130
  • 1
  • 14
  • 36

1 Answers1

0

You have to create a static.json file to your root folder (next to packages.json) with the following configuration.

{
  "root": "build/",
  "clean_urls": false,
  "routes": {
    "/**": "index.html"
  }
}

Hope this will work for you!

  • Would this go next to my server package.json or my client side package.json? My app is currently coupled and I am not sure where to place the static.json. I have tried placing it in both the root and in the client and neither work so far :( – pythonNovice Oct 23 '19 at 15:53
  • @pythonNovice did you find a solution> – Masksway May 12 '21 at 14:36