Last updated: Apr 7, 2024
Reading time·4 min

<Route> component<Route> componentThe "[Component] is not a <Route> component. All component children of
<Routes> must be a <Route> or <React.Fragment>" most commonly occurs
when we use a component as a child of a Route component.
To solve the error, use the element prop instead.

Here is the complete error stack trace.
Uncaught Error: [Component] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment> at invariant (history.ts:480:1) at components.tsx:582:1 at react.development.js:1195:1 at react.development.js:1158:1 at mapIntoArray (react.development.js:1049:1) at mapChildren (react.development.js:1157:1) at Object.forEachChildren [as forEach] (react.development.js:1194:1) at createRoutesFromChildren (components.tsx:566:1) at components.tsx:615:1 at react.development.js:1195:1
Here is an example of how the error occurs.
// ⛔️ Uncaught Error: [About] is not a <Route> component. <Route path="/"> <About /> </Route>
Notice that the <About /> component is passed as a child to the Route
component.
Instead, you should use the element prop to specify which component should be
rendered when the given path is matched.
// ✅ Correct <Route path="/about" element={<About />} /> <Route path="/" element={<Home />} />
You can also pass nested components to the element prop.
<Route path="/" element={ <ProtectedRoute user={user}> <Home /> </ProtectedRoute> } />
Only Route or React.Fragment components are valid children of the Routes
component.
The main reason for this change is that the <Route><Children/></Route> syntax
is now reserved for nesting routes.
You can read more about the rationale in this section of the React Router docs.
Here is the complete, working component.
import {Route, Link, Routes, BrowserRouter} from 'react-router-dom'; function App() { return ( <BrowserRouter> <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> </BrowserRouter> ); } function Home() { return <h2>Home Content</h2>; } function About() { return <h2>About Content</h2>; } export default App;

Make sure to not wrap your Router inside another Router.
In some cases, you might want to wrap your Route components into another
component to apply styling.
For example, assume you have to wrap multiple components in a container class.
import { Outlet } from 'react-router-dom'; function Dashboard() { return ( <div className='container'> <h1>Dashboard</h1> <Outlet /> </div> ); }
The Outlet component is used in a parent route to render their child route elements.
Let's assume your App component looks as follows.
function App() { return ( <Routes> <Route path="/" element={<Dashboard />}> <Route path="messages" element={<DashboardMessages />} /> <Route path="tasks" element={<DashboardTasks />} /> </Route> </Routes> ); }
We used an Outlet component to render the child route elements of the
Dashboard Route.
The Outlet component will render:
<DashboardMessages/> component when the URL is /messages<DashboardTasks /> component when the URL is /tasks.null when the URL is /.Note that you should no longer pass the exact prop to Route components.

The following line causes an error when using React.js with TypeScript.
// ⛔️ Property 'exact' does not exist on type <Route exact path="/" element={<Home />} />
Instead, remove the exact prop.
// ✅ Correct <Route path="/" element={<Home />} />
The default behavior of Route paths is to match exactly.
If you want to match more of the URL because your component contains nested
routes, use a trailing asterisk /* in the path.
// ✅ Correct <Route path="/products/*" element={<Products />} />
Now your Products component might contain nested routes.
function Products() { return ( <div> <nav> <Link to="/">All Products</Link> </nav> <Routes> <Route path="/" element={<ProductsList />} /> <Route path=":id" element={<SpecificProduct />} /> </Routes> </div> ) }
The <Link to> and Route path values are automatically scoped to the
/products URL prefix because the Products component is only rendered when
the URL matches /products/*.
If you need to get the ID from a URL in React Router, click on the link and follow the instructions.
You can use the following approach if you need to handle Private/Protected Routes.
import {Navigate, useLocation} from 'react-router-dom' export function RequireAuth({ children }) { const isAuthenticated = false; // your logic here const location = useLocation(); if (!isAuthenticated) { return <Navigate to="/login" state={{ from: location }} />; } return children; }
If the user is not authenticated, we redirect
them to the /login page.
The location of where they were trying to navigate before getting redirected is
saved using the state prop.
We can use this location to redirect them to a specific page, rather than a
generic page, such as /.
Then you would use the RequireAuth component as follows.
import {Route} from 'react-router-dom' import {RequireAuth} from './RequireAuth' <Route path="/protected" element={ <RequireAuth> <ProtectedPage /> </RequireAuth> } />
An alternative approach is to use the Outlet component.
import {Outlet, Navigate} from 'react-router-dom'; export const PrivateRoute = () => { const isAuth = null; // Your logic here return isAuth ? <Outlet /> : <Navigate to="/login" />; }
The Outlet component is used in a parent route to render their child route elements.
If the user is authenticated, then the Outlet component renders its child
route elements.
Otherwise, the user gets redirected to the /login page.
Here is how you would use the PrivateRoute component.
import {Routes, Route} from 'react-router-dom'; import {PrivateRoute} from './PrivateRoute' // ... <Routes> <Route path='/' element={<PrivateRoute/>}> {/* Specify private routes here */} <Route path='/' element={<Home/>}/> <Route path='/change-password' element={<ChangePassword/>}/> </Route> {/* Specify public routes here */} <Route path='/register' element={<Register/>}/> <Route path='/login' element={<Login/>}/> </Routes>
Notice that we nest the private routes inside the Route that has
PrivateRoute as its element.
Outlet component is used in a parent route to render their child route elements.In other words, if the user tries to access /:
PrivateRoute component checks if the user is authenticated.<Home /> component is rendered./login page.If the user tries to navigate to /change-password:
PrivateRoute component checks if the user is authenticated.<ChangePassword /> component is rendered./login.