Skip to content

React Router v6: Fixing "A Route is only ever to be used as the child of Routes element" Error

Problem Statement

When working with React Router, you may encounter the error:

"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."

This error typically occurs when:

  • You're using React Router v6 or later
  • Your Route components are not wrapped in a Routes component
  • You're using the outdated syntax from React Router v5

Solution

React Router v6 introduced significant changes to how routes are defined and structured. Here's how to fix the common issues:

1. Wrap Routes in a Routes Component

In v6, all Route components must be direct children of a Routes component:

jsx
import { Routes, Route } from "react-router-dom";
import Welcome from "./Pages/Welcome";
import Game from "./Pages/Game";
import Leaderboard from "./Pages/Leaderboard";

function App() {
  return (
    <div>
      <Routes>
        <Route path="/welcome" element={<Welcome />} />
        <Route path="/game" element={<Game />} />
        <Route path="/leaderboard" element={<Leaderboard />} />
      </Routes>
    </div>
  );
}

export default App;

2. Use the Correct Syntax for Route Components

React Router v6 changed from children syntax to an element prop:

jsx
// CORRECT for v6
<Route path="/welcome" element={<Welcome />} />
jsx
// INCORRECT for v6 (v5 syntax)
<Route path="/welcome">
  <Welcome />
</Route>

3. Complete Setup Example

Here's a complete working example with both index.js and App.js:

index.js:

jsx
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from "./App";

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root')
);

App.js:

jsx
import { Routes, Route } from "react-router-dom";
import Welcome from "./Pages/Welcome";
import Game from "./Pages/Game";
import Leaderboard from "./Pages/Leaderboard";

function App() {
  return (
    <div>
      <Routes>
        <Route path="/welcome" element={<Welcome />} />
        <Route path="/game" element={<Game />} />
        <Route path="/leaderboard" element={<Leaderboard />} />
      </Routes>
    </div>
  );
}

export default App;

Why This Changed in React Router v6

React Router v6 introduced several major improvements:

  1. Routes replaced Switch - Offers better matching and relative routing
  2. element prop replaced children - More consistent with React patterns
  3. Automatic route ranking - Smarter matching without needing exact prop
  4. Relative links and routes - Better support for nested routing

Version Compatibility

If you're following a tutorial, check which version of React Router it uses. Many tutorials were written for v5 and need adjustment for v6.

Alternative: Using useRoutes Hook

For complex routing structures, you can use the useRoutes hook:

jsx
import { useRoutes } from "react-router-dom";
import Welcome from "./Pages/Welcome";
import Game from "./Pages/Game";
import Leaderboard from "./Pages/Leaderboard";

function App() {
  const routes = useRoutes([
    { path: "/welcome", element: <Welcome /> },
    { path: "/game", element: <Game /> },
    { path: "/leaderboard", element: <Leaderboard /> }
  ]);
  
  return <div>{routes}</div>;
}

export default App;

Migration Tips

If you need to downgrade temporarily (not recommended for new projects):

bash
npm install react-router-dom@5.3.0

However, it's better to update your code to v6 syntax as v5 will eventually become deprecated.

Best Practice

Always check your React Router version and consult the official documentation for the correct syntax for your version.

Summary

The "A Route is only ever to be used as the child of Routes element" error is resolved by:

  1. Wrapping all Route components in a Routes component
  2. Using the element prop instead of children
  3. Ensuring you're using the correct import statements

By following these patterns, you'll be able to successfully implement routing in your React applications using React Router v6.