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

ReactBEGINNERMEDIUMUpdated Dec 10, 2025· 110 views

This error occurs when you try to use the useSearchParams hook from React Router outside of a component wrapped by a Router provider. The hook requires the routing context to access URL search parameters.

Quick fix

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

// App.tsx or main.tsx
import { BrowserRouter } from 'react-router-dom';
import { Routes, Route } from 'react-router-dom';
import MyComponent from './components/MyComponent';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<MyComponent />} />
        {/* other routes */}
      </Routes>
    </BrowserRouter>
  );
}

export default App;
  1. Verify your router setup at the application root
  2. Move useSearchParams usage inside routed components
  3. Fix test environments by wrapping with MemoryRouter
  4. Check for nested router issues
react — error
// App.tsx or main.tsx
import { BrowserRouter } from 'react-router-dom';
import { Routes, Route } from 'react-router-dom';
import MyComponent from './components/MyComponent';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<MyComponent />} />
{/* other routes */}
</Routes>
</BrowserRouter>
);
}
export default App;
useSearchParams() may be used only in the context of a <Router> component.

What this error means

The `useSearchParams` hook is part of React Router and relies on the Router context to function. When you call this hook in a component that isn't rendered within a `<BrowserRouter>`, `<RouterProvider>`, or similar Router component, React Router cannot access the routing information it needs. This is a common issue that happens when: - Components using the hook are rendered outside your router setup - Testing components in isolation without proper Router wrapper - Calling the hook at the root level before the Router is initialized - Rendering components that use routing hooks in non-routed parts of your application The error is React Router's way of enforcing that routing hooks can only be used within the proper routing context. This ensures the hook can safely access and modify URL search parameters.

Typical symptoms

  • Application crashes immediately when component mounts
  • Error thrown: "useSearchParams() may be used only in the context of a <Router> component"
  • Component using useSearchParams fails to render
  • Tests fail when running components that use the hook
  • Error occurs after moving component to a different part of the app

Common causes

  1. Component using useSearchParams is not wrapped by BrowserRouter or RouterProvider
  2. Hook is called outside the Routes component tree
  3. Component hierarchy issue where routing context is not available
  4. Testing components without wrapping them in a router provider
  5. Using the hook in a component rendered outside the main App router setup
  6. Calling useSearchParams in utility functions or class components outside routing context

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

1Verify your router setup at the application root

First, check that your application is properly wrapped with a Router provider at the root level. Open your main entry point (usually App.tsx or main.tsx) and ensure it looks like this:

tsx
// App.tsx or main.tsx
import { BrowserRouter } from 'react-router-dom';
import { Routes, Route } from 'react-router-dom';
import MyComponent from './components/MyComponent';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<MyComponent />} />
        {/* other routes */}
      </Routes>
    </BrowserRouter>
  );
}

export default App;

If you're using React Router v6.4+ with data routers, use RouterProvider instead:

tsx
import { RouterProvider, createBrowserRouter } from 'react-router-dom';
import MyComponent from './components/MyComponent';

const router = createBrowserRouter([
  {
    path: '/',
    element: <MyComponent />,
  },
]);

function App() {
  return <RouterProvider router={router} />;
}

export default App;
2Move useSearchParams usage inside routed components

Ensure that any component using useSearchParams is rendered as part of your route tree. The hook must be called within components that are descendants of the Router provider.

Incorrect (component outside router):

tsx
// main.tsx
import { BrowserRouter } from 'react-router-dom';
import { useSearchParams } from 'react-router-dom'; // ❌ Won't work here

function App() {
  const [searchParams] = useSearchParams(); // ❌ Error!

  return (
    <BrowserRouter>
      {/* routes */}
    </BrowserRouter>
  );
}

Correct (component inside router):

tsx
// MyComponent.tsx
import { useSearchParams } from 'react-router-dom';

function MyComponent() {
  const [searchParams, setSearchParams] = useSearchParams(); // ✅ Works
  const query = searchParams.get('q');

  return <div>Search query: {query}</div>;
}

// App.tsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import MyComponent from './MyComponent';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<MyComponent />} />
      </Routes>
    </BrowserRouter>
  );
}
3Fix test environments by wrapping with MemoryRouter

When testing components that use useSearchParams, wrap them in a Router provider. Use MemoryRouter for tests since it doesn't require a browser environment:

tsx
// MyComponent.test.tsx
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import MyComponent from './MyComponent';

describe('MyComponent', () => {
  it('should render without errors', () => {
    render(
      <MemoryRouter initialEntries={['/?q=test']}>
        <MyComponent />
      </MemoryRouter>
    );

    expect(screen.getByText(/Search query: test/i)).toBeInTheDocument();
  });
});

For more complex test scenarios with routes:

tsx
import { render } from '@testing-library/react';
import { MemoryRouter, Routes, Route } from 'react-router-dom';
import MyComponent from './MyComponent';

test('renders with search params', () => {
  render(
    <MemoryRouter initialEntries={['/?filter=active&page=2']}>
      <Routes>
        <Route path="/" element={<MyComponent />} />
      </Routes>
    </MemoryRouter>
  );

  // assertions...
});
4Check for nested router issues

Ensure you don't have nested BrowserRouter components or conflicting router setups. You should only have ONE router provider at the root of your application.

Incorrect (nested routers):

tsx
function App() {
  return (
    <BrowserRouter>
      <Layout>
        <BrowserRouter> {/* ❌ Don't nest routers */}
          <Routes>
            <Route path="/" element={<Home />} />
          </Routes>
        </BrowserRouter>
      </Layout>
    </BrowserRouter>
  );
}

Correct (single router):

tsx
function App() {
  return (
    <BrowserRouter>
      <Layout>
        <Routes>
          <Route path="/" element={<Home />} />
        </Routes>
      </Layout>
    </BrowserRouter>
  );
}

If you need nested routes, use <Outlet /> instead of nesting routers.

5Use alternative approaches for non-routed contexts

If you truly need to access search parameters outside a routed component (like in a utility function), use the native URLSearchParams API directly:

tsx
// utils/searchParams.ts
export function getSearchParam(key: string): string | null {
  if (typeof window === 'undefined') return null;

  const searchParams = new URLSearchParams(window.location.search);
  return searchParams.get(key);
}

export function getAllSearchParams(): Record<string, string> {
  if (typeof window === 'undefined') return {};

  const searchParams = new URLSearchParams(window.location.search);
  const params: Record<string, string> = {};

  searchParams.forEach((value, key) => {
    params[key] = value;
  });

  return params;
}

However, this approach won't trigger re-renders when search params change, so prefer using the hook within routed components whenever possible.

Advanced notes

Understanding React Router Context Architecture

React Router uses React's Context API to provide routing state throughout your component tree. Hooks like useSearchParams, useNavigate, useLocation, and useParams all rely on this context. When you call these hooks, React looks up the component tree for the nearest Router context provider.

React Router v6.4+ Data Routers

If you're using the newer data router APIs (createBrowserRouter, RouterProvider), the context is provided by RouterProvider. Components rendered through the router configuration have access to all routing hooks:

tsx
const router = createBrowserRouter([
  {
    path: '/',
    element: <Root />,
    children: [
      {
        path: 'search',
        element: <SearchPage />, // Can use useSearchParams
      },
    ],
  },
]);

Server-Side Rendering Considerations

When using SSR frameworks like Remix or Next.js with React Router, be aware that useSearchParams behavior may differ. In Remix, for example, you might use useSearchParams from @remix-run/react instead. Check your framework's documentation for the correct import.

Custom Router Implementations

If you're building a custom router or integrating with other routing libraries, you'll need to provide the Router context yourself. This is rarely necessary but can be done using React Router's lower-level APIs like Router component with a custom history object.

Migration from Class Components

Class components cannot use hooks directly. If you need search params in a class component, either:
1. Convert to a function component
2. Create a HOC that wraps the component and passes search params as props
3. Use withRouter (deprecated in v6) or create a custom wrapper component

Frequently asked questions

What does "useSearchParams() may be used only in the context of a <Router> compon" mean?
The useSearchParams hook is part of React Router and relies on the Router context to function. When you call this hook in a component that isn't rendered within a <BrowserRouter>, <RouterProvider>, or similar Router component, React Router cannot access the routing information it needs. This is a common issue that happens when: - Components using the hook are rendered outside your router setup - Testing components in isolation without proper Router wrapper - Calling the hook at the root level before the Router is initialized - Rendering components that use routing hooks in non-routed parts of your application The error is React Router's way of enforcing that routing hooks can only be used within the proper routing context.
How do I fix "useSearchParams() may be used only in the context of a <Router> compon"?
This error occurs when you try to use the useSearchParams hook from React Router outside of a component wrapped by a Router provider. The hook requires the routing context to access URL search parameters.
What causes "useSearchParams() may be used only in the context of a <Router> compon"?
Component using useSearchParams is not wrapped by BrowserRouter or RouterProvider Hook is called outside the Routes component tree Component hierarchy issue where routing context is not available
Is the "useSearchParams() may be used only in the context of a <Router> compon" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading