How to fix useNavigate() may be used only in the context of a <Router> component. in React

ReactBEGINNERMEDIUMUpdated Dec 22, 2025· 118 views

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>
);
  1. Move Router to application root
  2. Check Router placement in component tree
  3. Wrap test components with Router
  4. Add Router decorator for Storybook
react — error
// 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>
);
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

  1. BrowserRouter or other Router component is placed at the same level or below where useNavigate is called
  2. App component uses useNavigate but Router wrapper is defined inside App instead of wrapping it
  3. Router provider is missing from the root of your application (index.js/main.tsx)
  4. Testing components that use useNavigate without wrapping them in a test Router
  5. Using useNavigate in Storybook stories without adding router decorators
  6. 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."

1Move Router to application root

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):

jsx
// 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:

jsx
// 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;
2Check Router placement in component tree

Verify that useNavigate is only used inside components that are children of your Router:

❌ Incorrect - Router inside component using the hook:

jsx
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:

jsx
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>;
}
3Wrap test components with Router

When testing components that use useNavigate, wrap them in a Router (typically MemoryRouter for tests):

jsx
// 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:

jsx
// 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:

jsx
import { renderWithRouter } from './test-utils';

test('my test', () => {
  renderWithRouter(<MyComponent />);
});
4Add Router decorator for Storybook

If you're using Storybook and your components use navigation hooks, add a router decorator:

jsx
// .storybook/preview.js
import { MemoryRouter } from 'react-router-dom';

export const decorators = [
  (Story) => (
    <MemoryRouter initialEntries={['/']}>
      <Story />
    </MemoryRouter>
  ),
];

Or add it to individual stories:

jsx
// 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:

jsx
// 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):

jsx
// 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') anywhere

Router 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