How to fix useLocation() may be used only in the context of a <Router> component. in React
This error occurs when calling useLocation or other React Router hooks outside the Router component's context. React Router hooks rely on context provided by BrowserRouter or other Router components, and must be called within child components.
Quick fix
Fixes useLocation() may be used only in the context of a <Router> component.
// ✅ Correct: Router at the root in index.tsx
import { BrowserRouter } from 'react-router-dom';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);- Verify Router component wraps your application root
- Move context providers inside the Router component
- Check for multiple react-router installations
- Wrap test components in Router for testing
// ✅ Correct: Router at the root in index.tsximport { BrowserRouter } from 'react-router-dom';import App from './App';ReactDOM.createRoot(document.getElementById('root')!).render(<React.StrictMode><BrowserRouter><App /></BrowserRouter></React.StrictMode>);useLocation() may be used only in the context of a <Router> component.
What this error means
This error is React Router's way of telling you that you're trying to use routing functionality in a component that doesn't have access to the Router context. React Router hooks like useLocation, useNavigate, useParams, and others depend on React Context to access routing state and functionality. The Router component (BrowserRouter, MemoryRouter, HashRouter, etc.) provides this context to all its child components through React's Context API. When you call useLocation outside of a Router component's tree, React Router can't find the context it needs to provide location information, resulting in this error. This is a protective measure to prevent runtime errors that would occur if the hook tried to access undefined routing context. The error most commonly appears when components using Router hooks are rendered before the Router component is mounted, when Router hooks are used in provider components that wrap the Router, or when multiple versions of react-router are installed causing context mismatches.
Typical symptoms
- Application crashes immediately on page load with an uncaught error
- Error appears when navigating to routes that use Router hooks
- Tests fail with 'useLocation may be used only in the context' error
- Error occurs after adding authentication or state management providers
- Components using useNavigate, useParams, or useLocation throw errors
- React DevTools shows Router hooks being called outside Router tree
- Error happens after upgrading React Router versions
Common causes
- Calling useLocation in a component that renders before or outside the Router component
- Auth providers or context providers wrapping the Router component instead of being nested inside it
- Using Router hooks in the root App component that renders the Router itself
- Calling Router hooks in custom providers that are parents of the Router
- Multiple versions of react-router or react-router-dom installed in node_modules
- Test files not wrapping components in a Router when testing components that use Router hooks
- Router hooks called in module-level code or outside React components
- Incorrect component hierarchy where Router is conditionally rendered after hook usage
How to fix "useLocation() may be used only in the context of a <Router> component."
Ensure BrowserRouter (or another Router) wraps all components that use Router hooks. The Router should be one of the outermost components in your app:
// ✅ Correct: Router at the root in index.tsx
import { BrowserRouter } from 'react-router-dom';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);// ❌ Incorrect: Using useLocation before Router
import { useLocation } from 'react-router-dom';
function App() {
const location = useLocation(); // Error! No Router context yet
return (
<BrowserRouter>
<Routes>{/* ... */}</Routes>
</BrowserRouter>
);
}Move any Router hooks from the component that renders the Router to child components inside the Router tree.
If you're using authentication or state management providers, ensure they're nested inside the Router, not wrapping it:
// ❌ Incorrect: AuthProvider wrapping Router
<AuthProvider>
<BrowserRouter>
<App />
</BrowserRouter>
</AuthProvider>
// ✅ Correct: AuthProvider inside Router
<BrowserRouter>
<AuthProvider>
<App />
</AuthProvider>
</BrowserRouter>This allows components within your auth provider to safely use Router hooks. If your auth provider needs routing information, create a wrapper component that uses the hooks:
<BrowserRouter>
<AuthProviderWithRouter>
<App />
</AuthProviderWithRouter>
</BrowserRouter>
// In AuthProviderWithRouter.tsx
function AuthProviderWithRouter({ children }) {
const location = useLocation(); // Now safe to use
// Auth logic using location
return <AuthProvider location={location}>{children}</AuthProvider>;
}Multiple versions of react-router packages can cause context mismatches. Check your package.json and node_modules:
# Check installed versions
npm list react-router react-router-dom
# Remove duplicate installations
rm -rf node_modules package-lock.json
npm installEnsure all react-router packages use the same version:
{
"dependencies": {
"react-router": "^6.20.0",
"react-router-dom": "^6.20.0"
}
}If using a library like react-admin that includes react-router, ensure you don't have conflicting versions in your dependencies.
When testing components that use Router hooks, wrap them in a test Router:
// Using React Testing Library
import { render } from '@testing-library/react';
import { BrowserRouter, MemoryRouter } from 'react-router-dom';
import MyComponent from './MyComponent';
test('renders component with routing', () => {
render(
<MemoryRouter initialEntries={['/']}>
<MyComponent />
</MemoryRouter>
);
// Your assertions
});For more control in tests, use MemoryRouter with initialEntries to set specific routes:
const { getByText } = render(
<MemoryRouter initialEntries={['/profile/123']}>
<Routes>
<Route path="/profile/:id" element={<ProfilePage />} />
</Routes>
</MemoryRouter>
);If you need to use Router hooks in conjunction with the Router setup, create a separate child component:
// ❌ Incorrect: Hook in same component as Router
function App() {
const location = useLocation(); // Error!
return (
<BrowserRouter>
<Routes>{/* ... */}</Routes>
</BrowserRouter>
);
}
// ✅ Correct: Split into parent and child
function App() {
return (
<BrowserRouter>
<AppContent />
</BrowserRouter>
);
}
function AppContent() {
const location = useLocation(); // Safe here
// Use location for analytics, auth checks, etc.
return <Routes>{/* ... */}</Routes>;
}This pattern is especially useful for analytics tracking, authentication checks, or scroll restoration that depend on routing state.
Advanced notes
React Router v6 Data APIs: If you're using React Router v6.4+ with createBrowserRouter and RouterProvider, the error can still occur if you try to use hooks outside the provider. Ensure RouterProvider is at the root and all components using hooks are in your route definitions or children of RouterProvider.
Server-Side Rendering: When using SSR with frameworks like Remix or Next.js with React Router, ensure your Router setup matches between server and client. StaticRouter on the server and BrowserRouter on the client should wrap the same component tree.
Micro-frontends: In micro-frontend architectures where multiple apps might use React Router, ensure each app manages its own Router instance and avoid trying to share Router context across app boundaries. Use memory routing or URL-based communication instead.
TypeScript Considerations: If using TypeScript with custom Router wrappers, ensure your types properly represent that components must be children of the Router. Use React.ComponentType or similar types that don't imply standalone usage.
Performance: Creating child components to use Router hooks has no meaningful performance impact. React's Context API is optimized for this pattern, and the component tree structure is the same whether hooks are in parent or child components.
Frequently asked questions
- What does "useLocation() may be used only in the context of a <Router> component." mean?
- This error is React Router's way of telling you that you're trying to use routing functionality in a component that doesn't have access to the Router context. React Router hooks like useLocation, useNavigate, useParams, and others depend on React Context to access routing state and functionality. ) provides this context to all its child components through React's Context API.
- How do I fix "useLocation() may be used only in the context of a <Router> component."?
- This error occurs when calling useLocation or other React Router hooks outside the Router component's context. React Router hooks rely on context provided by BrowserRouter or other Router components, and must be called within child components.
- What causes "useLocation() may be used only in the context of a <Router> component."?
- Calling useLocation in a component that renders before or outside the Router component Auth providers or context providers wrapping the Router component instead of being nested inside it Using Router hooks in the root App component that renders the Router itself
- Is the "useLocation() may be used only in the context of a <Router> component." error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.