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.
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.
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.
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.
Prop spreading could cause security issues
Prop spreading could cause security issues
Error: error:0308010C:digital envelope routines::unsupported
Error: error:0308010C:digital envelope routines::unsupported
React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render.
React Hook useEffect placed inside a condition
Hook can only be called inside the body of a function component
Hook can only be called inside the body of a function component
Rollup failed to resolve import during build
How to fix "Rollup failed to resolve import" in React