React: useHref() may only be used in the context of a component

The React error “Uncaught Error: useHref() may be used only in the context of a component.” occurs when you use a react-router-dom <Link> component outside the context of a <Router> component. To fix this, move all of your links inside the router.

This error was discovered when working on our React routes guide. If you haven’t read it yet and wan to learn more about adding routes to your React app, you should check it out.

react-router-dom makes routing in React applications incredibly easy. It does, however, have pretty strict requirements as to the placement of its components. One of the requirements is that <Link> components only be used within one of the <Router> components. In our example, our router is a <HashRouter>.

Let’s take a look at the situation that caused this error.

Problem: You have one or more <Link> components outside the router context

Below is our top-level component, App.js, where we define our <HashRouter> and its routes:

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}>
            <div id="menu">
                Menu: 
                <Link to="/">Home</Link> 
                <Link to="/users">Users</Link>
            </div>
            <HashRouter>
                <Routes>
                    <Route path="/" element={<MessagesPage />} />
                    <Route path="/users" element={<UsersPage />} />
                </Routes>
            </HashRouter>
        </Provider>
    );
}

export default App;
JavaScript

Pay special attention to where we placed our menu. If we try to run this, we’ll get the following error:

As the error states, we have to move that menu into the <HashRouter> component tags. The reason for this is that the <Link> component needs information from the <HashRouter>, and can only access it when placed within its tags.

Solution: Move all <Link> components inside the router

To fix this, we move the menu inside the <HashRouter> tags like this:

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

And now the app will display properly with no errors in the console.

Conclusion

When using react-router-dom, it’s important to make sure your components are in the right place. Anything requiring access to the router needs to be within its context, i.e., within the <[Hash|Browser]Router> tags. That includes <Link>s and <Route>s. This is because these components need to access information contained in the router, and can only do so if they’re inside it.