How to fix useNavigate() may be used only in the context of a <Router> component. in React
This error occurs when the useNavigate hook from React Router is called in a component that is not wrapped within a Router provider (like BrowserRouter or MemoryRouter). The useNavigate hook requires access to React Router's context to function.
Quick fix
Fixes useNavigate() may be used only in the context of a <Router> component.
// src/index.js or src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);- Move Router to application root
- Check Router placement in component tree
- Wrap test components with Router
- Add Router decorator for Storybook
// src/index.js or src/main.tsximport React from 'react';import ReactDOM from 'react-dom/client';import { BrowserRouter } from 'react-router-dom';import App from './App';const root = ReactDOM.createRoot(document.getElementById('root'));root.render(<React.StrictMode><BrowserRouter><App /></BrowserRouter></React.StrictMode>);useNavigate() may be used only in the context of a <Router> component.
What this error means
This error indicates that you're trying to use React Router's useNavigate hook in a component that doesn't have access to the Router context. In React Router v6+, hooks like useNavigate, useLocation, and useParams depend on context provided by Router components (BrowserRouter, HashRouter, MemoryRouter, etc.). The error typically occurs when: - The Router component is defined in the same file or component where you're using useNavigate - Your component tree isn't properly wrapped with a Router at the root level - You're testing components without wrapping them in a Router - You're using the hook in a utility function or class that's outside the component tree
Typical symptoms
- Application crashes on mount with "useNavigate() may be used only in the context of a <Router> component"
- Error occurs when clicking navigation buttons or links
- Tests fail with Router context errors
- Storybook stories using navigation hooks throw errors
- Error appears after upgrading React Router versions
Common causes
- BrowserRouter or other Router component is placed at the same level or below where useNavigate is called
- App component uses useNavigate but Router wrapper is defined inside App instead of wrapping it
- Router provider is missing from the root of your application (index.js/main.tsx)
- Testing components that use useNavigate without wrapping them in a test Router
- Using useNavigate in Storybook stories without adding router decorators
- Attempting to use navigation hooks in utility files or outside React components
How to fix "useNavigate() may be used only in the context of a <Router> component."
The most common fix is to ensure your Router wraps your entire application at the root level. Move your Router component to your entry file (index.js, index.tsx, or main.tsx):
// src/index.js or src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);Now any component inside App can safely use useNavigate:
// src/App.js
import { useNavigate } from 'react-router-dom';
function App() {
const navigate = useNavigate();
const handleClick = () => {
navigate('/dashboard');
};
return <button onClick={handleClick}>Go to Dashboard</button>;
}
export default App;Verify that useNavigate is only used inside components that are children of your Router:
❌ Incorrect - Router inside component using the hook:
import { BrowserRouter, useNavigate } from 'react-router-dom';
function App() {
const navigate = useNavigate(); // ❌ Error! Router not yet mounted
return (
<BrowserRouter>
<div>Content</div>
</BrowserRouter>
);
}✅ Correct - Router wraps component using the hook:
import { BrowserRouter } from 'react-router-dom';
import Navigation from './Navigation';
function App() {
return (
<BrowserRouter>
<Navigation /> {/* ✅ Can use useNavigate */}
</BrowserRouter>
);
}
// Navigation.js
import { useNavigate } from 'react-router-dom';
function Navigation() {
const navigate = useNavigate(); // ✅ Works!
return <nav>...</nav>;
}When testing components that use useNavigate, wrap them in a Router (typically MemoryRouter for tests):
// Component.test.js
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import MyComponent from './MyComponent';
test('renders navigation button', () => {
render(
<MemoryRouter>
<MyComponent />
</MemoryRouter>
);
expect(screen.getByText('Navigate')).toBeInTheDocument();
});For multiple tests, create a custom render helper:
// test-utils.js
import { render } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
export function renderWithRouter(ui, { route = '/' } = {}) {
window.history.pushState({}, 'Test page', route);
return render(
<MemoryRouter initialEntries={[route]}>
{ui}
</MemoryRouter>
);
}Then use it in tests:
import { renderWithRouter } from './test-utils';
test('my test', () => {
renderWithRouter(<MyComponent />);
});If you're using Storybook and your components use navigation hooks, add a router decorator:
// .storybook/preview.js
import { MemoryRouter } from 'react-router-dom';
export const decorators = [
(Story) => (
<MemoryRouter initialEntries={['/']}>
<Story />
</MemoryRouter>
),
];Or add it to individual stories:
// MyComponent.stories.jsx
import { MemoryRouter } from 'react-router-dom';
import MyComponent from './MyComponent';
export default {
title: 'MyComponent',
component: MyComponent,
decorators: [
(Story) => (
<MemoryRouter>
<Story />
</MemoryRouter>
),
],
};
export const Default = {
args: {},
};Advanced notes
Navigation outside React components:
If you need to navigate programmatically from outside React components (like Redux thunks, API utilities, or event handlers), React Router v6 doesn't provide a built-in solution. You have a few options:
1. Pass navigate function as parameter:
// utils.js
export function logout(navigate) {
clearSession();
navigate('/login');
}
// Component.jsx
const navigate = useNavigate();
const handleLogout = () => logout(navigate);2. Create a custom history object (advanced):
// history.js
export const history = { navigate: null, location: null };
// App.jsx
import { useNavigate, useLocation } from 'react-router-dom';
import { history } from './history';
function HistoryHandler() {
history.navigate = useNavigate();
history.location = useLocation();
return null;
}
function App() {
return (
<BrowserRouter>
<HistoryHandler />
{/* rest of app */}
</BrowserRouter>
);
}
// Now you can use history.navigate('/path') anywhereRouter variants:
Different Router components for different use cases:
- BrowserRouter: Standard for web apps (uses HTML5 history API)
- HashRouter: Uses URL hash (#) for older browsers or static hosting
- MemoryRouter: Keeps history in memory (ideal for tests and React Native)
- StaticRouter: For server-side rendering
- NativeRouter: For React Native apps
React Router v7 changes:
React Router v7 introduced some breaking changes. If you upgraded and suddenly see this error:
- Ensure you're using the correct import paths
- Check that any third-party routing libraries (like Clerk) are compatible with v7
- Some packages may need their own Router setup - consult their migration guides
Frequently asked questions
- What does "useNavigate() may be used only in the context of a <Router> component." mean?
- This error indicates that you're trying to use React Router's useNavigate hook in a component that doesn't have access to the Router context. ).
- How do I fix "useNavigate() may be used only in the context of a <Router> component."?
- This error occurs when the useNavigate hook from React Router is called in a component that is not wrapped within a Router provider (like BrowserRouter or MemoryRouter). The useNavigate hook requires access to React Router's context to function.
- What causes "useNavigate() may be used only in the context of a <Router> component."?
- BrowserRouter or other Router component is placed at the same level or below where useNavigate is called App component uses useNavigate but Router wrapper is defined inside App instead of wrapping it Router provider is missing from the root of your application (index.js/main.tsx)
- Is the "useNavigate() may be used only in the context of a <Router> component." error serious?
- It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- 📚React Official Documentation
- 📝
- 🐙github.com - 8701(GitHub)
- 🔗
- 🔗
- 🔗
- 🔗