# React Router: “Attempted import error: 'Switch' is not exported from 'react-router-dom'”

> Switch, useHistory or Redirect is not exported from react-router-dom: the app has React Router v6 but code written for v5. The v6 names, and the fix.

Canonical: https://app369.com/fix/react-router-switch-is-not-exported/
Last updated: 2026-11-08

The build fails with Switch is not exported from react-router-dom (webpack says export 'Switch' (imported as 'Switch') was not found in 'react-router-dom'; Vite says it does not provide an export named Switch), or the same error for useHistory, Redirect or withRouter. The project installed React Router v6 or later, but the code, a tutorial or a generated component uses the v5 API. v6 renamed or removed those exports.

**Short answer**

Rename to the v6 API: Switch becomes Routes, useHistory becomes useNavigate, Redirect becomes Navigate, and component={Page} becomes element={<Page />}. Check the version with npm ls react-router-dom. If you need the app running today and the codebase is large, pin react-router-dom@5 as a stopgap, or use the react-router-dom-v5-compat package to migrate route by route.

## **Which v5 name you used, and the v6 replacement**

1. 01 ### **Switch: use Routes, and element instead of component**
  > “React Router v6 introduces a Routes component that is kind of like Switch, but a lot more powerful.” [**React Router, Upgrading from v5**](https://reactrouter.com/6.30.0/upgrading/v5) Wrap routes in Routes. Each Route takes element with JSX, not component or render, and exact is gone because v6 picks the best match. Routes are chosen based on the best match instead of being traversed in order, so the order of your routes no longer decides which one renders.```
// v5
<Switch>
  <Route exact path="/" component={Home} />
  <Route path="/users/:id" component={User} />
</Switch>

// v6
<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/users/:id" element={<User />} />
</Routes>
```
2. 02 ### **useHistory: use useNavigate**
  > “Most of the time this means changing useHistory to useNavigate and changing the history.push or history.replace callsite.” [**React Router, Upgrading from v5**](https://reactrouter.com/6.30.0/upgrading/v5) useNavigate returns a function. history.push('/home') becomes navigate('/home'), and history.replace('/home') becomes navigate('/home', { replace: true }).```
import { useNavigate } from 'react-router-dom';

function SaveButton() {
  const navigate = useNavigate();
  return <button onClick={() => navigate('/done')}>Save</button>;
}
```
3. 03 ### **Redirect: use Navigate** A redirect route becomes a Route whose element is <Navigate to="/new" replace />. A private route wrapper returns <Navigate to="/login" /> when the user isn’t signed in, and is used as an element, not as a custom child of Routes.```
<Route path="/old" element={<Navigate to="/new" replace />} />
```
4. 04 ### **withRouter and class components** withRouter was removed. In a function component, use useNavigate, useParams and useLocation. For a class component, write a small wrapper function component that calls those hooks and passes the values down as props. Other renames come up next: useRouteMatch becomes useMatch, NavLink activeClassName becomes a className function, Prompt was removed, and a parent route with child routes needs path="/users/*" or an <Outlet />. useNavigate() may be used only in the context of a <Router> means the component renders outside BrowserRouter.

Checked against the vendor’s docs on November 8, 2026: [React Router: Upgrading from v5](https://reactrouter.com/6.30.0/upgrading/v5).

## **Rather hand it over?**

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

- [from $450**App Fix Ticket**One reproducible bug in an existing mobile or web app, diagnosed and fixed.**See scope and start**](https://app369.com/fixed-price/flutter-firebase-bug-fix/)
- [from $450**AI-Built App Rescue**A Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.****No issues worth fixing, no charge.**** If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.**See scope and start**](https://app369.com/fixed-price/ai-app-rescue/)

Related: [**React “Element type is invalid”**](https://app369.com/fix/react-element-type-is-invalid/) · [**Page not found on refresh (Netlify, Vercel)**](https://app369.com/fix/page-not-found-on-refresh-netlify-vercel/) · [**React “Invalid hook call”**](https://app369.com/fix/react-invalid-hook-call/)

Questions

## **More on this error**

<details>

<summary>**Should I just downgrade to v5? **+</summary>

Only as a stopgap. npm install react-router-dom@5 gets an old app building again, but v5 gets no new features. Migrate to the current version when you can; the upgrade guide covers each rename.

</details>

<details>

<summary>**Does this apply to React Router v7? **+</summary>

Yes. v7 keeps the v6 names (Routes, useNavigate, Navigate), so v5 code fails the same way. In v7 the main package is react-router; react-router-dom still works as a re-export.

</details>

<details>

<summary>**Can you fix it for me? **+</summary>

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.

</details>

A different error?

## **Describe it and get a written quote**

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; Simon replies by email, usually within one business day.

[**Describe your problem **→](https://app369.com/contact/) [**All fixes**](https://app369.com/fix/)