Search code examples
reactjsreact-routercreate-react-app

Where do you configure what your React app server is sending back?


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>

Solution

  • 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>
        </>
          )
    };