docs/01-app/03-api-reference/04-functions/use-router.mdx
The useRouter hook allows you to programmatically change routes inside Client Components.
Recommendation: Use the
<Link>component for navigation unless you have a specific requirement for usinguseRouter.
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
useRouter()router.push(href: string, { scroll: boolean, transitionTypes: string[] }): Perform a client-side navigation to the provided route. Adds a new entry into the browser's history stack. The optional transitionTypes are passed to React.addTransitionType inside the navigation Transition.router.replace(href: string, { scroll: boolean, transitionTypes: string[] }): Perform a client-side navigation to the provided route without adding a new entry into the browser’s history stack. The optional transitionTypes are passed to React.addTransitionType inside the navigation Transition.router.refresh(): Refresh the current route. Making a new request to the server, re-fetching data requests, and re-rendering Server Components. The client will merge the updated React Server Component payload without losing unaffected client-side React (e.g. useState) or browser state (e.g. scroll position). This clears the Client Cache for the current route, but does not invalidate the server-side cache. Use revalidatePath or revalidateTag to invalidate server-side cached data.router.prefetch(href: string, options?: { onInvalidate?: () => void }): Prefetch the provided route for faster client-side transitions. The optional onInvalidate callback is called when the prefetched data becomes stale.router.back(): Navigate back to the previous route in the browser’s history stack.router.forward(): Navigate forwards to the next page in the browser’s history stack.router.bfcacheId: An opaque string identifier scoped to the current route segment. It changes when the surrounding segment is freshly created by a push or replace navigation, and stays the same for back/forward navigations, router.refresh(), and search-param- or hash-only navigations. See bfcacheId below for details.Good to know:
- You must not send untrusted or unsanitized URLs to
router.pushorrouter.replace, as this can open your site to cross-site scripting (XSS) vulnerabilities. For example,javascript:URLs sent torouter.pushorrouter.replacewill be executed in the context of your page.- The
<Link>component automatically prefetch routes as they become visible in the viewport.refresh()could re-produce the same result if fetch requests are cached. Other Request-time APIs likecookiesandheaderscould also change the response.- The
onInvalidatecallback is called at most once per prefetch request. It signals when you may want to trigger a new prefetch for updated route data.
next/routeruseRouter hook should be imported from next/navigation and not next/router when using the App Routerpathname string has been removed and is replaced by usePathname()query object has been removed and is replaced by useSearchParams()router.events has been replaced. See below.View the full migration guide.
You can listen for page changes by composing other Client Component hooks like usePathname and useSearchParams.
'use client'
import { useEffect } from 'react'
import { usePathname, useSearchParams } from 'next/navigation'
export function NavigationEvents() {
const pathname = usePathname()
const searchParams = useSearchParams()
useEffect(() => {
const url = `${pathname}?${searchParams}`
console.log(url)
// You can now use the current URL
// ...
}, [pathname, searchParams])
return '...'
}
Which can be imported into a layout.
import { Suspense } from 'react'
import { NavigationEvents } from './components/navigation-events'
export default function Layout({ children }) {
return (
<html lang="en">
<body>
{children}
<Suspense fallback={null}>
<NavigationEvents />
</Suspense>
</body>
</html>
)
}
Good to know:
<NavigationEvents>is wrapped in aSuspenseboundary becauseuseSearchParams()causes client-side rendering up to the closestSuspenseboundary during prerendering. Learn more.
By default, Next.js will scroll to the top of the page when navigating to a new route. You can disable this behavior by passing scroll: false to router.push() or router.replace().
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button
type="button"
onClick={() => router.push('/dashboard', { scroll: false })}
>
Dashboard
</button>
)
}
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button
type="button"
onClick={() => router.push('/dashboard', { scroll: false })}
>
Dashboard
</button>
)
}
bfcacheIdrouter.bfcacheId is an opaque string identifier scoped to the current route segment. It changes when the surrounding segment is freshly created by a push or replace navigation, and stays the same for back/forward navigations, router.refresh(), and search-param- or hash-only navigations.
The recommended use is to pass it as a React key to opt out of state preservation on fresh navigations, while still restoring it during a back/forward navigation:
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const { bfcacheId } = useRouter()
return <form key={bfcacheId}></form>
}
When cacheComponents is enabled, the App Router preserves Client Component state across navigations using React <Activity>. Keying a component on bfcacheId resets it on each fresh navigation while still preserving its state across browser back/forward navigations. See Preserving UI state for the recommended per-pattern resets.
Good to know: Instead of
bfcacheId, prefer resetting state explicitly in an event handler (for example,onSubmit) or deriving a key from your data (for example, a draft id from the server). UsebfcacheIdonly as a last resort, like when migrating an existing codebase.
| Version | Changes |
|---|---|
v15.4.0 | Optional onInvalidate callback for router.prefetch introduced |
v13.0.0 | useRouter from next/navigation introduced. |