Export 'Switch' (imported as 'Switch') was not found in 'react-router-dom'

avatar
Borislav Hadzhiev

Last updated: Jan 15, 2023
3 min

banner

# Export 'Switch' (imported as 'Switch') was not found in 'react-router-dom'

To solve the error "export 'Switch' (imported as 'Switch') was not found in 'react-router-dom'", import Routes instead of Switch and wrap your <Route /> components with a <Routes> component.

export switch imported as switch not found

App.js
import React from 'react'; // ๐Ÿ‘‡๏ธ import Routes instead of Switch ๐Ÿ‘‡๏ธ import {BrowserRouter as Router, Route, Link, Routes} from 'react-router-dom'; export default function App() { return ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> </ul> </nav> {/* ๐Ÿ‘‡๏ธ Wrap your Route components in a Routes component */} <Routes> <Route path="/about" element={<About />} /> <Route path="/" element={<Home />} /> </Routes> </div> </Router> ); } function Home() { return <h2>Home</h2>; } function About() { return <h2>About</h2>; }

using routes instead of switch

Make sure to not render a Router within another Router.

In React router v6, we have to replace the <Switch> component with <Routes>.

Whenever the location changes, the <Routes> component looks through its child <Route /> components and renders the component with the best matching path.

Make sure your project is running the latest version by issuing the npm install react-router-dom@latest command.

shell
# with NPM npm install react-router-dom@latest # or with YARN yarn add react-router-dom@latest
If you don't want to update your code, you can install v5 of react-router-dom by running npm install react-router-dom@5.2.0 from your project's root directory.

In React Router v6, the exact prop has been removed and you can put your routes in whatever order you wish and the router automatically detects the best route for the current URL.

In React Router v6, instead of passing a children prop to the Route components, we use the element prop, e.g. <Route path="/about" element={<About />} />.

# Using dynamic or wildcard placeholders

React Router v6 uses a simplified path format where <Route path> has 2 kinds of placeholders:

  • dynamic :id params
  • * wildcards

The * wildcard syntax can only be used at the end of a path.

App.js
import React from 'react'; import {BrowserRouter as Router, Route, Link, Routes} from 'react-router-dom'; import {useParams} from 'react-router-dom'; export default function App() { return ( <Router> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> <li> {/* ๐Ÿ‘‡๏ธ link to dynamic path */} <Link to="/users/4200">Users</Link> </li> <li> {/* ๐Ÿ‘‡๏ธ link to catch all route */} <Link to="/does-not-exist">Catch all route</Link> </li> </ul> </nav> {/* ๐Ÿ‘‡๏ธ Wrap your Route components in a Routes component */} <Routes> <Route path="/about" element={<About />} /> {/* ๐Ÿ‘‡๏ธ handle dynamic path */} <Route path="/users/:userId" element={<Users />} /> <Route path="/" element={<Home />} /> {/* ๐Ÿ‘‡๏ธ only match this when no other routes match */} <Route path="*" element={ <div> <h2>404 Page not found etc</h2> </div> } /> </Routes> </div> </Router> ); } function Home() { return <h2>Home</h2>; } function About() { return <h2>About</h2>; } function Users() { const params = useParams(); return <h2>Users: {params.userId}</h2>; }

using dynamic or wildcard placeholders

The route <Route path="/users/:userId" element={<Users />} /> uses a dynamic userId parameter, which we can access by using the useParams hook.

The route would match anything after /users/, e.g. /users/123 or /users/asdf.

The route that has a path equal to * serves as a catch-all route. It only matches when no other routes do.

I've also written a detailed guide on how to handle 404 Page not found in React Router.

# A <Route> is only ever to be used as the child of <Routes> element, never rendered directly

If you forget to wrap your Route components in a Routes component, you would get the following error:

  • A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.

route is only ever to be used as child of routes element

The following code sample causes the error.

App.js
<Router> <div> <Link to="/">Home</Link> <Link to="/about">About</Link> {/* โ›”๏ธ A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>. */} {/* Forgot to wrap <Route /> components in <Routes /> */} <Route path="/about" element={<About />} /> <Route path="/" element={<Home />} /> </div> </Router>

The <Routes /> component is responsible to look through its <Route /> components and render the best match based on the specified path.

To solve the error, make sure to always wrap your <Route /> components in a <Routes /> component.

Here is a complete working example.

App.js
import { BrowserRouter as Router, Route, Link, Routes, } from 'react-router-dom'; export default function App() { return ( <Router> <div> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> <Routes> <Route path="/about" element={<About />} /> <Route path="/" element={<Home />} /> </Routes> </div> </Router> ); } function Home() { return <h2>Home</h2>; } function About() { return <h2>About</h2>; }

using routes instead of switch

You should also make sure that all children of Routes are Route components or React.Fragments.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev