I have a front-end React app and a back-end Express app running on two different Heroku dynos. As far as I am aware, the front-end server has no knowledge of my Express app except when I specifically send queries to that API. Rather, my React app is somehow being served based on default settings, probably provided by create-react-app.
However, I am running into this issue currently with my React Router routes, and the solution they provide is to add this code to the server:
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "index.html"));
});
Well sure, that code is already present in my Express app, but we've already established that's not what's serving my React app. So where do I add the same (or similar) code to ensure that I am catching all possible routes and sending them to "index.html"?
UPDATE:
From additional reading I've done, it looks like the Webpack way of routing back to index.html is by setting historyApiFallback
to true in webpack.config.js. However, I am not looking to eject CRA, as I think that will cause more long-term problems than it solves. In my node_modules/react-scripts/config folder, in the webpackDevServer.config.js file, this already exists:
historyApiFallback: {
// Paths with dots should still use the history fallback.
// See https://github.com/facebook/create-react-app/issues/387.
disableDotRule: true,
}
Unless I'm misreading this doc, it seems as though that is equivalent to saying historyApiFallback = true. So shouldn't this already be working?
The other thing I found is that most people only encounter problems with this behavior during development because the hot reloading feature is only turned on in development. However, my understanding is when I deploy to Heroku, it builds a production version of my app automatically. But the automatic redirect from "/signup" to "/" is happening there as well. If the issue isn't solved by historyApiFallback, what could it be?
Routing file:
<Switch>
<Route exact path="/" component={App} />
<Route path="/home" component={LandingPage} />
<Route exact path="/signup" render={props => (
<AuthPage authType="signup" {...props} />
)} />
<Route path="/login" render={props => (
<AuthPage authType="login" {...props} />
)} />
<Route path="/about" component={AboutPage} />
</Switch>
The answer turned out to be far more simple and frustrating than any of the above answers. It turns out I had a component at a higher level than my component, which ran a hook that evaluated whether the user was authenticated and displayed a different NavBar in each scenario. Somehow this must have thrown off the lower-level routes and caused the redirect. When I moved the NavBar into the Routing file, things started working.
New code for Routing.js:
export const Routing = () => {
const { location } = useReactRouter();
const showSiteNav = () => {
console.log(location);
if (location.pathname === "/") {
return false;
}
return true;
}
return (
<>
{showSiteNav() ? <SiteNav /> : null}
<Switch>
<Route exact path="/" component={App} />
<Route path="/home" component={LandingPage} />
<Route exact path="/signup" render={props => (
<AuthPage authType="signup" {...props} />
)} />
<Route path="/login" render={props => (
<AuthPage authType="login" {...props} />
)} />
</Switch>
</>
)
};