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.

Mugen
  • 8,301
  • 10
  • 62
  • 140

5 Answers5

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>
Mezbaul Haque
  • 1,242
  • 9
  • 13
10
<Router>
    <Switch>
        // ...your routes and then
        <Route path="*" render={() => <Redirect to="/" />}
    </Switch>
</Router>
zemil
  • 3,235
  • 2
  • 24
  • 33
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>
Community
  • 1
  • 1
cbdeveloper
  • 27,898
  • 37
  • 155
  • 336
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>
mellis481
  • 4,332
  • 12
  • 71
  • 118
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

Abhisar Tripathi
  • 1,569
  • 10
  • 21
  • this doesn't work, if I add this redirect to, say, `about`. when I try to directly access `
    /code` I'm also getting redirected.
    – Mugen Jun 20 '19 at 11:24