Combination of Sidebar and Nested routes using react-router-dom v4 / v5

Viewed 1687

I want to implement somewhat a combination of nested routes and sidebar routes in a single route file. I want the components to render like this.

"/" --- Registration page
"/login" ---- Login Page
"/application" --- Application Page
"/dashboard" --- Dashboard page with Sidebar and Application components
"/dashboard/application" --- Dashboard page with Sidebar and Application components
"/dashboard/user" --- Dashboard page with Sidebar and User components

I have my routes setup like this

      <Switch>
        <Route path="/" component={withAuth(Registration)} />
        <Route path="/login" component={withAuth(Login)} />
        <Route path={'/dashboard'} component={withAuth(Dashboard)}/>        
      </Switch>

Inside the dashboard page I have implemented basically the sidebar example from react-router-dom website.

It is working fine, however i want to put all the routing in a single file.

Something like this

<Switch>
  <Route path="/" component={withAuth(Registration)} />
  <Route path="/login" component={withAuth(Login)} />
  <Route path={'/dashboard'} component={withAuth(Dashboard)} children={[Sidebar, Application]}/>
  <Route path="/dashboard/application" component={withAuth(Dashboard)} children={[Sidebar, Application]}/>
  <Route path="/dashboard/user" component={withAuth(Dashboard)} children={[Sidebar, User]}/>
</Switch>

The above code is fictional code but it is to give an idea of what I'm trying to achieve. I tried solution from a similar question, but it didn't work for me.

How do i put all the routing in a single file and take care of sidebar routing and nested routing in react-router-dom v4/v5?

I have created a example code sandbox, Please try this example.

1 Answers

While I think having all your routes in one file has become anti-pattern, I think you can achieve something close enough to what you're looking for - specifically, getting all the routes to reside in the same file.

The main trick is using the switch like a normal switch. The last case in the Switch becomes the default case (or route).

You also need to use exact because without it, it will match the URL / every time. The same is true of the second Switch inside InternalRoutes. If you don't include exact, it will match /dashboard every time and never get to /dashboard/application or dashboard/user. You'll still need the Routes component to be wrapped in a BrowserRouter component.

import React from 'react';
import { Switch, Route } from 'react-router-dom';

const Routes = props => {
  return (
    <Switch>
      <Route exact path="/" component={withAuth(Registration)} />
      <Route exact path="/login" component={withAuth(Login)} />
      <Route component={withAuth(InternalRoutes)} />
    </Switch>
  );
};

const InternalRoutes = props => {
  return (
    <Switch>
    <Route exact path="/dashboard" component={withAuth(Dashboard)} children={[Sidebar, Application]}/>
    <Route exact path="/dashboard/application" component={withAuth(Dashboard)} children={[Sidebar, Application]}/>
    <Route exact path="/dashboard/user" component={withAuth(Dashboard)} children={[Sidebar, User]}/>
    <Route component={NotFoundComponent} />
  );
};

const NotFoundComponent = props => {
  return <div>URL Not Found</div>;
};

export default Routes;
Related