DEV Community

Devin Rasmussen
Devin Rasmussen

Posted on

Ignore react-router's basename

Suppose we have a routing tree like such in our notifications service

<HashRouter>
  <Switch>
    <Route path='/notifications/dashboard' component={A} />
    <Route path='/notifications/:id' component={A} />
    ...
Enter fullscreen mode Exit fullscreen mode

If every path in this particular service contains notifications, it might be tempting to simply add a basename prop to HashRouter.

<HashRouter basename='notifications'>
Enter fullscreen mode Exit fullscreen mode

This does make it really convenient when we have a link to a page in the same service. Instead of

<Link to='/notifications/dashboard' />
Enter fullscreen mode Exit fullscreen mode

We can do

<Link to='/dashboard' />
Enter fullscreen mode Exit fullscreen mode

The fundamental flaw with basename is its totality. There is no way to escape its effects (at least with react-router-dom components).

Say we want to direct the user out of the notification service with a URL, there is no way to do so with Link

<Link to='/tasks/123' />
// yields <a href="/notifications/tasks/123" />
Enter fullscreen mode Exit fullscreen mode

This is also a hindrance to a Redirect

<Route path="/dashboard" 
  render={() => hasPermissions ? <Dashboard /> : <Redirect to="/403" 
/>
// redirects to "/notifications/403"
Enter fullscreen mode Exit fullscreen mode

One should therefore proceed cautiously (probably never in the microservice case) with basename. As the documenation notes:

The base URL for all locations. If your app is served from a sub-directory on your server, you’ll want to set this to the sub-directory

Alternatively, we can nest routes like so

<Route path="/notifications"
  render={({match: {url} }) => (
    <>
      <Route path={`${url}/dashboard`} component={Dashboard}
Enter fullscreen mode Exit fullscreen mode

But soon with react-router v6 nested routes will just work

<Route path="users" element={<Users />}>
  <Route path="/" element={<UsersIndex />} />
  <Route path=":id" element={<UserProfile />} />
Enter fullscreen mode Exit fullscreen mode

Discussion (0)