1

I'm setting up a server backend in express for a React application which is using React-Router v4. So far, I've set up Express so that any request is redirected to index.html, allowing React Router to do the rest of the work. This works for the routes '/beats', '/loops', '/kits', etc. The problem arises when there are multiple directories in the url, such as with the url '/beats/1/name-of-beat' (which is parsed as '/beats/:id/:name?' in react-router).

Using this express code:

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

app.get('/*', (req, res) => {
  res.sendFile(path.join(__dirname, '../frontend/build/index.html'));
});

This will redirect all requests to /kit, /beats, and the like to index.html, and all the <script> sources will still work. However, when trying to reach '/beats/1/name', index.html is served, but the <script> tags are also served the index.html, resulting in index.html loading in the browser but none of the javascript.

This happens if I add any other directories to the url in addition to the first, so '/beats/example' or '/beats/1/2/3' but not for '/example' (which would correctly show the 404 configured in react-router).

If it's needed, here's the router code:

<Router>
    <div className="App">
        <Header />
        <Switch>
            <Route exact path="/" component={Home} />
            <Route path="/kits" component={Kits} />
            <Route exact path="/beats" component={Beats} />
            <Route path="/beats/:id/:beatName?" component={SoundPage} />
            <Route path="/loops" component={Loops} />
            <Route path="/contact" component={Contact} />
            <Route component={NoMatch} />
          </Switch>
    </div>
</Router>

Here's the built index.html script tags:

<script src="./static/js/1.731b4af1.chunk.js"></script>
<script src="./static/js/main.498cadba.chunk.js"></script>

And here's the project structure:

-frontend
  -build
    -static
    -index.html
  -src
  -public
-backend
  -server.js

1 Answers1

0

Long story short, your nested routes will need to use the match property. Your routes will be nested in a drop-down structure, where each successive Route will be included within the next matching Component's render method. Watch this video to understand what I mean: React Router V4 Nested Routes

An alternative to using dynamic nested routes, would be to use a query parameter structure, where /beats/:query would be /beat/find?id=12345&beatName="Example Beat", which you can find an example here: React Router V4 Nested Routes Match Params Not Accessible At Root Level

The first example is more common in forums (like Reddit), while the second example is more common in web store-fronts (like Amazon).

Matt Carlotta
  • 18,972
  • 4
  • 39
  • 51
  • **Solution:** I heeded your advice to nest my routes, however, I solved the issue through a separate solution. The issue was actually in the built index.html, which was sourcing the ` – Richard Petrosino Jan 23 '19 at 03:10