React: Matched leaf route does not have an element

The react-router-dom error “Matched leaf route at location “/” does not have an element. This means it will render an with a null value by default resulting in an “empty” page.” is caused by not setting the element property of a <Route> component. Fix this by ensuring the element property is set to the element you want displayed at that route.

This error was discovered while creating the SuperTokens tutorial. If you want to learn more about how to use SuperTokens to secure your app, check out that article.

In react-router-dom, you have to set the element property of a <Route> component for it to display when the user visits that route. In my case, I used component instead of element, which resulted in getting this error.

Let’s look at an example.

Problem: you didn’t set the element property on your Route

Below is code from our react-router-dom tutorial as an example. It’s also available on GitHub if you want to learn more about how to use react-router-dom in your app.

import { Provider } from "urql";
import { urqlClient } from "./utils";
import { HashRouter, Route, Routes, Link } from "react-router-dom";

import MessagesPage from "./MessagesPage";
import UsersPage from "./UsersPage";

function App() {
    return (
        <Provider value={urqlClient}>
            <HashRouter>
                <div id="menu">
                    Menu: 
                    <Link to="/">Home</Link> 
                    <Link to="/users">Users</Link>
                </div>
                <Routes>
                    <Route path="/" component={<MessagesPage />} />
                    <Route path="/users" component={<UsersPage />} />
                </Routes>
            </HashRouter>
        </Provider>
    );
}

export default App;
JavaScript

Here, we have some routes defined within the <Routes> tags, / and /users. There’s a problem with our routes, though. Can you tell what it is?

                </div>
                <Routes>
                    <Route path="/" component={<MessagesPage />} />
                    <Route path="/users" component={<UsersPage />} />
                </Routes>
            </HashRouter>
JavaScript

What we did here was accidentally set the component property instead of the element property. There isn’t a component property to set on a <Route> element, so it does nothing.

In React, if you set a property that isn’t used, you don’t get an error. Instead, when we try to run this, you’ll get the following warning from react-router-dom and a blank space where your route should be rendering:

The fix is simple, so let’s get into that next.

Solution: make sure your route has the element property set

Highlighted below is the simple fix we need to make this work:

import { Provider } from "urql";
import { urqlClient } from "./utils";
import { HashRouter, Route, Routes, Link } from "react-router-dom";

import MessagesPage from "./MessagesPage";
import UsersPage from "./UsersPage";

function App() {
    return (
        <Provider value={urqlClient}>
            <HashRouter>
                <div id="menu">
                    Menu: 
                    <Link to="/">Home</Link> 
                    <Link to="/users">Users</Link>
                </div>
                <Routes>
                    <Route path="/" element={<MessagesPage />} />
                    <Route path="/users" element={<UsersPage />} />
                </Routes>
            </HashRouter>
        </Provider>
    );
}

export default App;
JavaScript

All you have to do is make sure your element property is set on all <Route>s. Another common error you can make here is not setting the element equal to an actual element, but the name of the component instead, such as element={MessagePage}.

Conclusion

When using react-router-dom to handle routing for your app, you have to set the element property of the <Route> component. If you accidentally forget to do this, or call it something else (like component) it won’t work, and you’ll get the warning “Matched leaf route does not have an element”.