How to define fallback route properly in react-router-dom
Asked Answered
G

6

21

I have the following Router definition:

<Router>
    <Route exact path='/' component={Home}/>
    <Route path='/about' component={About}/>
    <Route path='/code' component={Code}/>
</Router>

I want any unmapped route (i.e /foo) to redirect back to root /.

I tried <Redirect .../> without success. Also adding a <Route /> without a path= resulted in a duplicated component on each page.

Grew answered 20/6, 2019 at 11:19 Comment(0)
D
31

Just place a redirect at the bottom like this and wrap your routes with Switch:

<Router>
    <Switch>
        <Route exact path='/' component={Home}/>
        <Route path='/about' component={About}/>
        <Route path='/code' component={Code}/>

        // Redirect all 404's to home
        <Redirect to='/' />
    </Switch>
</Router>
Daisey answered 20/6, 2019 at 11:27 Comment(0)
B
12
<Router>
    <Switch>
        // ...your routes and then
        <Route path="*" render={() => <Redirect to="/" />}
    </Switch>
</Router>
Brahui answered 20/6, 2019 at 11:31 Comment(0)
M
5

You need to do it inside a <Switch> component.

// IMPORT

import {
  BrowserRouter as Router,
  Route,
  Link,
  Switch,
  Redirect
} from "react-router-dom";

---------- 
// USAGE

<Switch>
  <Route path="/" exact component={Home} />
  <Redirect from="/old-match" to="/will-match" />
  <Route path="/will-match" component={WillMatch} />
  <Route component={NoMatch} />
</Switch>

As you can see from React Router Docs.

Switch

Renders the first child <Route> or <Redirect> that matches the location.

How is this different than just using a bunch of s?

<Switch> is unique in that it renders a route exclusively. In contrast, every <Route> that matches the location renders inclusively. Consider this code:

<Route path="/about" component={About}/>
<Route path="/:user" component={User}/>
<Route component={NoMatch}/>

If the URL is /about, then <About>, <User>, and <NoMatch> will all render because they all match the path. This is by design, allowing us to compose <Route>s into our apps in many ways, like sidebars and breadcrumbs, bootstrap tabs, etc.

Occasionally, however, we want to pick only one <Route> to render. If we’re at /about we don’t want to also match /:user (or show our “404” page). Here’s how to do it with Switch:

import { Switch, Route } from 'react-router'

<Switch>
 <Route exact path="/" component={Home}/>
 <Route path="/about" component={About}/>
 <Route path="/:user" component={User}/>
 <Route component={NoMatch}/>
</Switch>
Motorboat answered 20/6, 2019 at 13:24 Comment(0)
R
3

I'm pretty surprised to see that none of the answers to this question are what I would consider correct in that they all use redirects which IMO is a poor user experience. The user will not know what URL is incorrect if you immediately redirect them to the 404 router.

The correct answer should be what is demonstrated in React Router's own documentation here.

<Switch>
  <Route exact path="/">
    <Home />
  </Route>
  <Route path="/old-match">
    <Redirect to="/will-match" />
  </Route>
  <Route path="/will-match">
    <WillMatch />
  </Route>
  <Route path="*">
    <NoMatch />
  </Route>
</Switch>
Riebling answered 31/5, 2022 at 19:22 Comment(0)
I
0

Please add a default route at the bottom of all Routes (add from attribute to redirect)

<Router>
    <Route exact path='/' component={Home}/>
    <Route path='/about' component={About}/>
    <Route path='/code' component={Code}/>
    <Redirect from="/" />
</Router>

working link https://stackblitz.com/edit/react-st9nug?file=index.js

Imagism answered 20/6, 2019 at 11:21 Comment(1)
this doesn't work, if I add this redirect to, say, about. when I try to directly access <address>/code I'm also getting redirected.Grew
B
0

In React Router v6, the Redirect component has been replaced with the Navigate component. So, instead of using Redirect to="/", you should use the Navigate component like this:

<Routes>
    {/* Define your other routes here */}
     <Route path="/home" element={<Home />} />
     {/* Redirect to /home */}
     <Route path="*" element={<Navigate to="/home" replace />} />
 </Routes>
Bogeyman answered 4/7 at 15:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.