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

ReactBEGINNERHIGHUpdated Dec 10, 2025· 133 views

This error occurs when the useNavigate hook or navigate() function is called outside the Router context. React Router hooks require components to be descendants of a Router component like BrowserRouter or RouterProvider.

Quick fix

Fixes useNavigate() may be used only in the context of a <Router> component

// src/index.tsx
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';

const rootElement = document.getElementById('root');
const root = createRoot(rootElement);

root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);
  1. Move Router to index.tsx or main entry point
  2. Use RouterProvider for React Router v6.4+ data features
  3. Wrap test components in Router for Jest/RTL tests
  4. Create history helper for navigation outside React components
react — error
// src/index.tsx
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
const rootElement = document.getElementById('root');
const root = createRoot(rootElement);
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
useNavigate() may be used only in the context of a <Router> component

What this error means

This error occurs when you try to use React Router's navigation features (useNavigate hook or navigate function) in a component that is not wrapped by a Router component. React Router hooks rely on context provided by Router components like BrowserRouter, HashRouter, or RouterProvider to access routing functionality. The useNavigate hook internally uses React Context to access the routing state and navigation functions. When a component using this hook is not a descendant of a Router component, React cannot find the required context, resulting in this error. This commonly happens when: the Router is placed inside App.tsx instead of index.tsx, components using navigation hooks are rendered outside the Router tree, or during testing when components aren't properly wrapped in a Router.

Typical symptoms

  • Application crashes immediately on mount with "useNavigate() may be used only in the context of a Router component"
  • Navigation functions fail when called from Redux actions, utility functions, or event handlers
  • Tests fail with Router context errors even though navigation works in development
  • Error appears after refactoring Router placement in component hierarchy
  • Components using useLocation, useParams, or useNavigate hooks throw context errors

Common causes

  1. Router component (BrowserRouter, HashRouter, etc.) is placed inside App.tsx instead of at the root in index.tsx
  2. Component using useNavigate hook is rendered outside the Router component tree
  3. Attempting to call navigate() from non-React code like Redux actions or utility modules
  4. Testing components that use navigation hooks without wrapping them in a Router
  5. Using RouterProvider incorrectly or passing children to it instead of using the router prop
  6. Multiple Router components creating conflicting contexts in the application

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

1Move Router to index.tsx or main entry point

The most common fix is to ensure your Router wraps your entire application at the root level. Move the Router component from App.tsx to your entry point:

tsx
// src/index.tsx
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';

const rootElement = document.getElementById('root');
const root = createRoot(rootElement);

root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

Your App.tsx should only contain Routes, not the Router wrapper:

tsx
// src/App.tsx
import { Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';

function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
    </Routes>
  );
}

export default App;
2Use RouterProvider for React Router v6.4+ data features

If using React Router v6.4+, prefer RouterProvider with createBrowserRouter for access to data APIs:

tsx
// src/main.tsx
import { createRoot } from 'react-dom/client';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import Root from './routes/root';
import About from './routes/about';
import ErrorPage from './error-page';

const router = createBrowserRouter([
  {
    path: '/',
    element: <Root />,
    errorElement: <ErrorPage />,
  },
  {
    path: '/about',
    element: <About />,
  },
]);

createRoot(document.getElementById('root')!).render(
  <RouterProvider router={router} />
);

Note: Do NOT pass children to RouterProvider - it only accepts the router prop.

3Wrap test components in Router for Jest/RTL tests

When testing components that use navigation hooks, wrap them in a Router:

tsx
// Using React Testing Library
import { render, screen } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
import MyComponent from './MyComponent';

test('renders navigation component', () => {
  render(
    <BrowserRouter>
      <MyComponent />
    </BrowserRouter>
  );

  expect(screen.getByText('Navigate')).toBeInTheDocument();
});

Or create a custom render helper:

tsx
// test-utils.tsx
import { ReactElement } from 'react';
import { render, RenderOptions } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';

function customRender(
  ui: ReactElement,
  options?: Omit<RenderOptions, 'wrapper'>
) {
  return render(ui, { wrapper: BrowserRouter, ...options });
}

export * from '@testing-library/react';
export { customRender as render };
4Create history helper for navigation outside React components

If you need to navigate from Redux actions, utility functions, or other non-React code, create a history helper:

tsx
// src/lib/navigation.ts
let navigate: ((to: string) => void) | null = null;

export function setNavigate(nav: (to: string) => void) {
  navigate = nav;
}

export function navigateOutsideReact(to: string) {
  if (navigate) {
    navigate(to);
  } else {
    console.error('Navigate function not initialized');
  }
}

Initialize it in a component inside your Router:

tsx
// src/App.tsx
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { setNavigate } from './lib/navigation';

function App() {
  const navigate = useNavigate();

  useEffect(() => {
    setNavigate(navigate);
  }, [navigate]);

  return (
    {/* Your routes */}
  );
}

Now you can use it anywhere:

tsx
// Redux action or utility function
import { navigateOutsideReact } from './lib/navigation';

export function logoutUser() {
  // Clear auth state
  localStorage.removeItem('token');

  // Navigate to login
  navigateOutsideReact('/login');
}
5Check for nested or duplicate Router components

Ensure you don't have multiple Router components creating conflicting contexts:

BAD - Multiple routers:

tsx
// index.tsx
<BrowserRouter>
  <App />
</BrowserRouter>

// App.tsx (WRONG - creates nested Router)
<BrowserRouter>
  <Routes>...</Routes>
</BrowserRouter>

GOOD - Single router:

tsx
// index.tsx
<BrowserRouter>
  <App />
</BrowserRouter>

// App.tsx (Correct - no Router wrapper)
<Routes>
  <Route path="/" element={<Home />} />
</Routes>

Search your codebase for all instances of BrowserRouter, HashRouter, MemoryRouter, and RouterProvider to identify duplicates.

Advanced notes

React Router v6.4+ Data APIs: If using loaders, actions, or other data features introduced in React Router v6.4, you must use createBrowserRouter with RouterProvider. The older BrowserRouter component doesn't support these features.

Memory Router for Testing: For more complex test scenarios, consider using MemoryRouter instead of BrowserRouter, as it doesn't require a DOM and allows you to control the history state:

tsx
import { MemoryRouter } from 'react-router-dom';

<MemoryRouter initialEntries={['/profile']}>
  <MyComponent />
</MemoryRouter>

Server-Side Rendering: When using React Router with SSR frameworks like Remix or Next.js with React Router, use StaticRouter on the server side and ensure client-side hydration uses the appropriate browser router.

Navigation After Authentication: A common pattern is redirecting after login. Ensure your authentication logic either happens inside a component within the Router tree, or use the history helper pattern described above to navigate from authentication utilities.

Strict Mode Double Mounting: React 18's Strict Mode intentionally double-mounts components in development. This doesn't cause the Router context error but may reveal issues with navigation side effects. Use cleanup functions in useEffect to prevent duplicate navigation calls.

Frequently asked questions

What does "useNavigate() may be used only in the context of a <Router> component" mean?
This error occurs when you try to use React Router's navigation features (useNavigate hook or navigate function) in a component that is not wrapped by a Router component. React Router hooks rely on context provided by Router components like BrowserRouter, HashRouter, or RouterProvider to access routing functionality. The useNavigate hook internally uses React Context to access the routing state and navigation functions.
How do I fix "useNavigate() may be used only in the context of a <Router> component"?
This error occurs when the useNavigate hook or navigate() function is called outside the Router context. React Router hooks require components to be descendants of a Router component like BrowserRouter or RouterProvider.
What causes "useNavigate() may be used only in the context of a <Router> component"?
Router component (BrowserRouter, HashRouter, etc.) is placed inside App.tsx instead of at the root in index.tsx Component using useNavigate hook is rendered outside the Router component tree Attempting to call navigate() from non-React code like Redux actions or utility modules
Is the "useNavigate() 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.

Official resources & further reading