# Next.js useLocation Replacement: Migrating from React Router to next/navigation

> Migrating to Next.js? Replace React Router's useLocation with next/navigation hooks like usePathname and useSearchParams for better routing management. Learn how to update your app seamlessly.

- Repository: [Vercel/next.js](https://github.com/vercel/next.js)
- Tags: migration-guide
- Published: 2026-02-20

---

**Replace React Router's `useLocation()` hook by combining `usePathname()` and `useSearchParams()` from `next/navigation`, using `useRouter()` when you need programmatic navigation.**

When migrating a React application to Next.js, you will need to adapt your routing logic to the App Router architecture. The `next/navigation` module provides granular hooks that together offer the same functionality as React Router's `useLocation`, but with better Server Component compatibility and optimized client-side performance.

## Why Next.js Uses Separate Hooks Instead of useLocation

React Router's `useLocation` returns a monolithic location object containing `pathname`, `search`, `hash`, `state`, and `key`. Next.js deliberately splits these concerns across multiple hooks to support **partial prerendering** and **React Server Components**.

According to the source code in [`packages/next/src/client/components/navigation.ts`](https://github.com/vercel/next.js/blob/main/packages/next/src/client/components/navigation.ts), the navigation API exposes atomic hooks that read from specialized React contexts. This design allows components to subscribe only to the specific URL segments they need, preventing unnecessary re-renders when unrelated parts of the URL change.

## The Equivalent Hooks in next/navigation

### usePathname for Path Access

The `usePathname` hook returns the current URL pathname as a string. In [`packages/next/src/client/components/navigation.ts`](https://github.com/vercel/next.js/blob/main/packages/next/src/client/components/navigation.ts) (lines 101-110), this hook reads from the `PathnameContext` provided by the App Router.

```tsx
"use client";

import { usePathname } from "next/navigation";

export default function PagePath() {
  const pathname = usePathname(); // Returns "/dashboard/settings"
  
  return <div>Current path: {pathname}</div>;
}

```

### useSearchParams for Query Strings

For search parameters, use `useSearchParams`, which returns a `URLSearchParams` instance. The implementation (lines 55-73 in [`navigation.ts`](https://github.com/vercel/next.js/blob/main/navigation.ts)) manages the query string state and provides reactive updates when parameters change.

```tsx
"use client";

import { useSearchParams } from "next/navigation";

export default function SearchDisplay() {
  const searchParams = useSearchParams();
  const category = searchParams.get("category");
  
  return <div>Category: {category ?? "All"}</div>;
}

```

### useRouter for Programmatic Navigation

When you need to navigate programmatically (equivalent to `history.push` or `history.replace`), use the `useRouter` hook. Lines 45-53 in [`navigation.ts`](https://github.com/vercel/next.js/blob/main/navigation.ts) define this hook, which provides methods like `push()`, `replace()`, and `refresh()`.

```tsx
"use client";

import { useRouter } from "next/navigation";

export default function NavigateButton() {
  const router = useRouter();
  
  const handleClick = () => {
    router.push("/dashboard?tab=analytics");
  };
  
  return <button onClick={handleClick}>Go to Dashboard</button>;
}

```

## Complete Migration Examples

### Reading the Full Location Object

To replicate `const location = useLocation()` from React Router, combine `usePathname` and `useSearchParams`:

```tsx
"use client";

import { usePathname, useSearchParams } from "next/navigation";

export default function LocationDisplay() {
  const pathname = usePathname();
  const searchParams = useSearchParams();
  
  const search = searchParams.toString();
  const fullUrl = `${pathname}${search ? `?${search}` : ""}`;
  
  return (
    <div>
      <p>Pathname: {pathname}</p>
      <p>Search: {search}</p>
      <p>Full URL: {fullUrl}</p>
    </div>
  );
}

```

### Creating a Custom useLocation Hook

For drop-in compatibility during migration, wrap the Next.js hooks to match React Router's API:

```tsx
"use client";

import { usePathname, useSearchParams } from "next/navigation";

export function useLocation() {
  const pathname = usePathname();
  const searchParams = useSearchParams();
  
  return {
    pathname,
    search: searchParams.toString() ? `?${searchParams.toString()}` : "",
    // Hash must be accessed from window.location as Next.js doesn't expose it
    hash: typeof window !== "undefined" ? window.location.hash : "",
    // Note: state is not supported; use React context or URL parameters instead
  };
}

```

## Key Source Files in the Repository

The Next.js navigation system relies on these core files in the [`vercel/next.js`](https://github.com/vercel/next.js/blob/main/vercel/next.js) repository:

- **[`packages/next/src/client/components/navigation.ts`](https://github.com/vercel/next.js/blob/main/packages/next/src/client/components/navigation.ts)** – Contains the primary hook implementations (`usePathname`, `useSearchParams`, `useRouter`) that read from internal contexts.
- **[`packages/next/src/shared/lib/hooks-client-context.shared-runtime.ts`](https://github.com/vercel/next.js/blob/main/packages/next/src/shared/lib/hooks-client-context.shared-runtime.ts)** – Provides the React contexts that supply pathname and search parameter data to the hooks.
- **[`packages/next/src/shared/lib/app-router-context.shared-runtime.ts`](https://github.com/vercel/next.js/blob/main/packages/next/src/shared/lib/app-router-context.shared-runtime.ts)** – Defines the `AppRouterContext` used by `useRouter` to access navigation methods.

## Summary

- **Replace `useLocation().pathname`** with `usePathname()` from `next/navigation`.
- **Replace `useLocation().search`** with `useSearchParams()` which returns a `URLSearchParams` object.
- **Use `useRouter()`** for programmatic navigation instead of `history.push` or `history.replace`.
- **No direct equivalent exists** for `location.hash` or `location.state`; access hash via `window.location` and manage state through React context or URL parameters.
- All navigation hooks require the `"use client"` directive and work exclusively in the App Router.

## Frequently Asked Questions

### How do I access the URL hash in Next.js?

Next.js does not expose the URL hash through `next/navigation` hooks because the hash is not sent to the server. Access it client-side using `window.location.hash` inside a `useEffect` or check `typeof window !== "undefined"` to prevent hydration mismatches.

### What replaces location.state from React Router?

Next.js does not implement `location.state` for the App Router. Store temporary navigation state using React Context, URL search parameters, or browser APIs like `sessionStorage` before navigating with `router.push()`.

### Can I use these hooks in Server Components?

No, `usePathname`, `useSearchParams`, and `useRouter` are client-side only and require the `"use client"` directive. In Server Components, access URL data through `searchParams` props passed to page components or use `headers()` and `cookies()` from `next/headers` for server-side URL inspection.

### Is useRouter from next/navigation different from next/router?

Yes, `useRouter` from `next/navigation` is specifically for the App Router and provides methods like `push()`, `replace()`, and `refresh()`. The `useRouter` from `next/router` is for the legacy Pages Router and has a different API. Always import from `next/navigation` when using the App Router.