useParams return value
useParams returns an object containing the current route's filled in dynamic parameters. Each property in the object is an active dynamic segment, where the property name is the segment's name and the property value is what the segment is filled in with. The property value will either be a string or array of strings depending on the type of dynamic segment. If the route contains no dynamic parameters, useParams returns an empty object. If used in Pages Router, useParams will return null on the initial render and updates with properties following the rules above once the router is ready.
useParams return examples
Examples of useParams return values: Route 'app/shop/page.js' with URL '/shop' returns {}. Route 'app/shop/[slug]/page.js' with URL '/shop/1' returns { slug: '1' }. Route 'app/shop/[tag]/[item]/page.js' with URL '/shop/1/2' returns { tag: '1', item: '2' }. Route 'app/shop/[...slug]/page.js' with URL '/shop/1/2' returns { slug: ['1', '2'] }.
useParams with TypeScript generics
useParams can be called with a TypeScript generic type parameter to specify the shape of the params object, for example: useParams<{ tag: string; item: string }>(). This provides type safety when accessing dynamic route parameters.
useParams TypeScript example with dynamic params
Example showing useParams with TypeScript: For route 'app/shop/[tag]/[item]' and URL '/shop/shoes/nike-air-max-97', the code 'const params = useParams<{ tag: string; item: string }>()' yields params = { tag: 'shoes', item: 'nike-air-max-97' }.
usePathname Client Components are not a de-optimization
Client Components using usePathname are an integral part of the Server Components architecture, not a de-optimization. A Client Component with usePathname is rendered into HTML on initial page load. When navigating to a new route, the component does not need to be re-fetched; instead it is downloaded once in the client JavaScript bundle and re-renders based on current state.
usePathname hook import and basic usage
usePathname is a Client Component hook imported from 'next/navigation'. It reads the current URL's pathname. It must be used in a Client Component (marked with 'use client'). It takes no parameters and returns a string of the current pathname.
usePathname pathname return values
usePathname returns a string of the current URL's pathname. Query string parameters are not included in the return value. Examples: URL '/' returns '/', URL '/dashboard' returns '/dashboard', URL '/dashboard?v=2' returns '/dashboard', URL '/blog/hello-world' returns '/blog/hello-world'.
usePathname cannot be used in Server Components
Reading the current URL from a Server Component using usePathname is not supported. This design is intentional to support layout state being preserved across page navigations.
usePathname with rewrites can cause hydration mismatch
If a page is statically prerendered and your app has rewrites in next.config or a Proxy file, reading the pathname with usePathname() can result in hydration mismatch errors. The initial server value may not match the actual browser pathname after routing occurs.
usePathname with Pages Router compatibility
If your project contains both an app and pages directory, usePathname may return null in Pages Router routes if the router is not yet initialized. This can occur with fallback routes or during Automatic Static Optimization in the Pages Router. Next.js automatically adjusts the return type of usePathname for compatibility between routing systems.
usePathname behavior with Cache Components enabled
When cacheComponents is enabled, usePathname may require a Suspense boundary. For static routes and routes with generateStaticParams, every route segment including dynamic params is known at build time, so usePathname resolves on the server with no Suspense boundary required. For routes with dynamic params not covered by generateStaticParams, the param is a fallback param unknown until request time, so usePathname suspends and requires wrapping in a Suspense boundary; otherwise the build fails.
usePathname Suspense boundary applies to static components
The Suspense boundary requirement for usePathname with Cache Components applies even when the component calling usePathname is itself static. For example, a sidebar with active links rendered in a layout will suspend on any page below it that has an unknown dynamic param. Wrap the component that calls usePathname (or a parent) in a Suspense boundary with a fallback to keep the rest of the layout prerendered.
usePathname example: respond to route change
To do something in response to a route change, use usePathname with useEffect and useSearchParams. Place usePathname() and useSearchParams() calls at the top level of the Client Component, then add useEffect with [pathname, searchParams] as dependencies to run code when routes change.
usePathname example: avoid hydration mismatch with rewrites
To avoid hydration mismatches with rewrites, design the UI so only a small isolated part depends on the client pathname. Use state initialized to empty string, then in useEffect set the state to the pathname value. This renders a stable fallback on the server and updates after mount, avoiding mismatch between server-rendered and client-rendered content.
usePathname introduced in v13.0.0
usePathname was introduced in Next.js version 13.0.0.
useRouter replaces query object from Pages Router
The query object has been removed from useRouter in the App Router and is replaced by useSearchParams().
useRouter replaces pathname from Pages Router
The pathname string has been removed from useRouter in the App Router and is replaced by usePathname().
useRouter hook import location
The useRouter hook should be imported from 'next/navigation' when using the App Router, not from 'next/router'.
router.refresh cache behavior with fetch requests
router.refresh() could reproduce the same result if fetch requests are cached. Other Request-time APIs like cookies and headers could also change the response.
Link component automatic prefetch behavior
The Link component automatically prefetches routes as they become visible in the viewport.
router.push method signature and behavior
router.push(href: string, { scroll: boolean, transitionTypes: string[] }) performs a client-side navigation to the provided route and adds a new entry into the browser's history stack. The optional transitionTypes are passed to React.addTransitionType inside the navigation Transition.
router.replace method signature and behavior
router.replace(href: string, { scroll: boolean, transitionTypes: string[] }) performs 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 method behavior
router.refresh() refreshes the current route by making a new request to the server, re-fetching data requests, and re-rendering Server Components. The client merges the updated React Server Component payload without losing unaffected client-side React (like useState) or browser state (like 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 method signature and behavior
router.prefetch(href: string, options?: { onInvalidate?: () => void }) prefetches the provided route for faster client-side transitions. The optional onInvalidate callback is called when the prefetched data becomes stale. The onInvalidate callback is called at most once per prefetch request and signals when you may want to trigger a new prefetch for updated route data.
router.back method behavior
router.back() navigates back to the previous route in the browser's history stack.
useRouter with cacheComponents and state preservation
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.
useRouter only works in Client Components
The useRouter hook allows you to programmatically change routes inside Client Components. It must be used in a component marked with 'use client'.
useRouter recommended usage pattern
The Link component is recommended for navigation unless you have a specific requirement for using useRouter.
router.push and router.replace transitionTypes parameter
The transitionTypes parameter is an optional string array passed to both router.push and router.replace. These types are passed to React.addTransitionType inside the navigation Transition.
useRouter router.push and router.replace scroll option
By default, Next.js scrolls 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().
router.prefetch onInvalidate callback introduced
The optional onInvalidate callback for router.prefetch was introduced in v15.4.0.
useRouter from next/navigation introduced
useRouter from next/navigation was introduced in v13.0.0.
router.forward method behavior
router.forward() navigates forwards to the next page in the browser's history stack.
useRouter XSS vulnerability warning
You must not send untrusted or unsanitized URLs to router.push or router.replace, as this can open your site to cross-site scripting (XSS) vulnerabilities. For example, javascript: URLs sent to router.push or router.replace will be executed in the context of your page.
router.bfcacheId property
router.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 back/forward navigation.
useRouter router.events replacement
router.events has been replaced in the App Router. You can listen for page changes by composing other Client Component hooks like usePathname and useSearchParams.
useSearchParams behavior with dynamic rendering
If a route is dynamically rendered, useSearchParams will be available on the server during the initial server render of the Client Component. Use the connection() function in a Server Component to force dynamic rendering.
useSearchParams hook purpose and type
useSearchParams is a Client Component hook from 'next/navigation' that lets you read the current URL's query string. It returns a read-only version of the URLSearchParams interface.
useSearchParams returns URLSearchParams interface
useSearchParams returns a read-only version of the URLSearchParams interface with utility methods including get(), has(), getAll(), keys(), values(), entries(), forEach(), and toString(). The returned object cannot be modified.
useSearchParams.get() method behavior
URLSearchParams.get() returns the first value associated with a search parameter. Returns '1' for /dashboard?a=1, returns '' (empty string) for /dashboard?a=, returns null for /dashboard?b=3 when parameter doesn't exist, and returns '1' for /dashboard?a=1&a=2 (use getAll() to get all values).
useSearchParams.has() method behavior
URLSearchParams.has() returns a boolean indicating if the given parameter exists. Returns true for /dashboard?a=1 and false for /dashboard?b=3.
useSearchParams not supported in Server Components
useSearchParams is a Client Component hook and is not supported in Server Components to prevent stale values during partial rendering. For Server Components, read the searchParams prop of the corresponding Page instead.
useSearchParams with prerendered routes requires Suspense
If a route is prerendered, calling useSearchParams will cause the Client Component tree up to the closest Suspense boundary to be client-side rendered. During production builds, a static page that calls useSearchParams from a Client Component must be wrapped in a Suspense boundary, otherwise the build fails with the Missing Suspense boundary with useSearchParams error.
Layouts do not receive searchParams prop
Layouts (Server Components) do not receive the searchParams prop because a shared layout is not re-rendered during navigation, which could lead to stale searchParams between navigations. Instead, use the Page searchParams prop or the useSearchParams hook in a Client Component.
useSearchParams with /pages directory returns nullable
If an application includes the /pages directory, useSearchParams will return ReadonlyURLSearchParams | null. The null value is for compatibility during migration since search params cannot be known during prerendering of a page that doesn't use getServerSideProps.
useSearchParams development behavior differs from production
In development, routes are rendered on-demand, so useSearchParams doesn't suspend and things may appear to work without Suspense. In production builds, a static page calling useSearchParams from a Client Component must be wrapped in a Suspense boundary.
useSearchParams basic example
To use useSearchParams, import it from 'next/navigation' in a Client Component, call it to get the searchParams object, then use methods like get() to access query parameters. Example: const searchParams = useSearchParams(); const search = searchParams.get('search'); // URL -> /dashboard?search=my-project -> 'my-project'
useSearchParams Suspense wrapping pattern
When useSearchParams is called in a prerendered route, wrap the Client Component using it in a Suspense boundary with a fallback. The fallback is rendered in the initial HTML and replaced with the component during React hydration. This allows parts of the route above to be prerendered while the dynamic part is client-side rendered.
useSearchParams with connection() for dynamic rendering
To force a route to be dynamically rendered so useSearchParams works without Suspense, call the connection() function from 'next/server' at the top of the Page Server Component. This semantically ties dynamic rendering to the incoming request and is preferred over export const dynamic = 'force-dynamic'.
Updating searchParams with useRouter example
To update searchParams, use useRouter, usePathname, and useSearchParams together. Create a helper function that constructs a new query string by creating a URLSearchParams object from the current searchParams, setting new values, and returning the string. Then use router.push() with the new URL or pass it to Link href.
useSearchParams introduced in version 13.0.0
useSearchParams was introduced in Next.js version 13.0.0.
useReportWebVitals sending results to external systems
```js
function postWebVitals(metric) {
const body = JSON.stringify(metric)
const url = 'https://example.com/analytics'
// Use `navigator.sendBeacon()` if available, falling back to `fetch()`.
if (navigator.sendBeacon) {
navigator.sendBeacon(url, body)
} else {
fetch(url, { body, method: 'POST', keepalive: true })
}
}
useReportWebVitals(postWebVitals)
```
This example demonstrates sending Web Vitals results to an external analytics endpoint using navigator.sendBeacon() as the preferred method, with a fallback to fetch().
useReportWebVitals Google Analytics integration example
```js
useReportWebVitals(metric => {
window.gtag('event', metric.name, {
value: Math.round(metric.name === 'CLS' ? metric.value * 1000 : metric.value), // values must be integers
event_label: metric.id, // id unique to current page load
non_interaction: true, // avoids affecting bounce rate.
});
})
```
This example shows how to integrate useReportWebVitals with Google Analytics. Use the metric.id value to construct metric distributions manually for calculating percentiles. CLS values must be multiplied by 1000 to convert to integers, while other metrics are rounded as-is.
useReportWebVitals hook overview
The useReportWebVitals hook allows you to report Core Web Vitals and can be used in combination with analytics services. New functions passed to useReportWebVitals are called with available metrics up to that point. To prevent reporting duplicated data, ensure that the callback function reference does not change.
useReportWebVitals App Router implementation
In the App Router, useReportWebVitals requires the 'use client' directive. The most performant approach is to create a separate client component that the root layout imports, confining the client boundary exclusively to the WebVitals component. The component should be placed in app/_components/web-vitals.js and imported into app/layout.js.
useReportWebVitals metric object properties
The metric object passed to useReportWebVitals contains the following properties:
- id: Unique identifier for the metric in the context of the current page load
- name: The name of the performance metric (TTFB, FCP, LCP, FID, CLS, INP)
- delta: The difference between the current value and the previous value of the metric, typically in milliseconds
- entries: An array of Performance Entries associated with the metric
- navigationType: Indicates the navigation type that triggered metric collection, with values 'navigate', 'reload', 'prerender', 'back-forward' (normalized from 'back_forward'), 'back-forward-cache' (BFCache restore), and 'restore' (page restored after discard)
- rating: A qualitative rating of the metric value, with possible values 'good', 'needs-improvement', and 'poor'
- value: The actual value or duration of the performance entry, typically in milliseconds
Web Vitals metrics tracked by useReportWebVitals
useReportWebVitals tracks the following Web Vitals metrics: Time to First Byte (TTFB), First Contentful Paint (FCP), Largest Contentful Paint (LCP), First Input Delay (FID), Cumulative Layout Shift (CLS), and Interaction to Next Paint (INP). You can handle all results using the name property of the metric object.
useReportWebVitals custom metrics (Pages Router only)
The Pages Router supports additional custom metrics that measure page hydration and rendering time: 'Next.js-hydration' (length of time for the page to start and finish hydrating in ms), 'Next.js-route-change-to-render' (length of time for a page to start rendering after a route change in ms), and 'Next.js-render' (length of time for a page to finish render after a route change in ms). These metrics work in all browsers that support the User Timing API.
useReportWebVitals App Router example with switch statement
```tsx
'use client'
import { useReportWebVitals } from 'next/web-vitals'
type ReportWebVitalsCallback = Parameters<typeof useReportWebVitals>[0]
const handleWebVitals: ReportWebVitalsCallback = (metric) => {
switch (metric.name) {
case 'FCP': {
// handle FCP results
}
case 'LCP': {
// handle LCP results
}
// ...
}
}
export function WebVitals() {
useReportWebVitals(handleWebVitals)
}
```
This example shows how to handle different Web Vitals metrics in the App Router using a switch statement on the metric.name property.
useReportWebVitals Pages Router example with switch statement
```jsx
import { useReportWebVitals } from 'next/web-vitals'
const handleWebVitals = (metric) => {
switch (metric.name) {
case 'FCP': {
// handle FCP results
}
case 'LCP': {
// handle LCP results
}
// ...
}
}
function MyApp({ Component, pageProps }) {
useReportWebVitals(handleWebVitals)
return <Component {...pageProps} />
}
```
This example shows how to handle different Web Vitals metrics in the Pages Router by implementing useReportWebVitals in pages/_app.js.