useParams
Source URL: https://nextjs.org/docs/pages/api-reference/functions/use-params
useParams
Section titled “useParams”useParams is a hook that lets you read a route’s dynamic params filled in by the current URL.
import { useParams } from 'next/navigation'
export default function ShopPage() { const params = useParams<{ slug: string }>()
if (!params) { // Render fallback UI while params are not yet available return null }
// Route -> /shop/[slug] // URL -> /shop/shoes // `params` -> { slug: 'shoes' } return <>Shop: {params.slug}</>}import { useParams } from 'next/navigation'
export default function ShopPage() { const params = useParams()
if (!params) { // Render fallback UI while params are not yet available return null }
// Route -> /shop/[slug] // URL -> /shop/shoes // `params` -> { slug: 'shoes' } return <>Shop: {params.slug}</>}Parameters
Section titled “Parameters”const params = useParams()useParams does not take any parameters.
Returns
Section titled “Returns”useParams returns an object containing the current route’s filled in dynamic parameters, or null during pre-rendering.
- Each property in the object is an active dynamic segment.
- 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
stringor array ofstrings depending on the type of dynamic segment. - If the route contains no dynamic parameters,
useParamsreturns an empty object.
For example:
| Route | URL | useParams() |
|---|---|---|
pages/shop/page.js | /shop | {} |
pages/shop/[slug].js | /shop/1 | { slug: '1' } |
pages/shop/[tag]/[item].js | /shop/1/2 | { tag: '1', item: '2' } |
pages/shop/[...slug].js | /shop/1/2 | { slug: ['1', '2'] } |
Good to know:
useParamsis a React Hook and cannot be used with classes.
Behavior
Section titled “Behavior”Behavior during pre-rendering
Section titled “Behavior during pre-rendering”For pages that are statically optimized, useParams will return null on the initial render. After hydration, the value will be updated to the actual params once the router is ready.
This is because params cannot be known during static generation for dynamic routes.
import { useParams } from 'next/navigation'
export default function ShopPage() { const params = useParams<{ slug: string }>()
if (!params) { // Return a fallback UI while params are loading // This prevents hydration mismatches return <ShopPageSkeleton /> }
return <>Shop: {params.slug}</>}import { useParams } from 'next/navigation'
export default function ShopPage() { const params = useParams()
if (!params) { // Return a fallback UI while params are loading // This prevents hydration mismatches return <ShopPageSkeleton /> }
return <>Shop: {params.slug}</>}Using with getServerSideProps
Section titled “Using with getServerSideProps”When using getServerSideProps, the page is server-rendered on each request and useParams will return the actual params immediately:
import { useParams } from 'next/navigation'
export default function ShopPage() { const params = useParams<{ slug: string }>()
// With getServerSideProps, this fallback is never rendered because // params is always available on the server. However, keeping // the fallback allows this component to be reused on other pages // that may not use getServerSideProps. if (!params) { return null }
return <>Shop: {params.slug}</>}
export async function getServerSideProps() { return { props: {} }}import { useParams } from 'next/navigation'
export default function ShopPage() { const params = useParams()
// With getServerSideProps, this fallback is never rendered because // params is always available on the server. However, keeping // the fallback allows this component to be reused on other pages // that may not use getServerSideProps. if (!params) { return null }
return <>Shop: {params.slug}</>}
export async function getServerSideProps() { return { props: {} }}Comparison with router.query
Section titled “Comparison with router.query”useParams only returns the dynamic route parameters, whereas router.query from useRouter includes both dynamic parameters and query string parameters.
import { useRouter } from 'next/router'import { useParams } from 'next/navigation'
export default function ShopPage() { const router = useRouter() const params = useParams()
// URL -> /shop/shoes?color=red
// router.query -> { slug: 'shoes', color: 'red' } // params -> { slug: 'shoes' }
// ...}import { useRouter } from 'next/router'import { useParams } from 'next/navigation'
export default function ShopPage() { const router = useRouter() const params = useParams()
// URL -> /shop/shoes?color=red
// router.query -> { slug: 'shoes', color: 'red' } // params -> { slug: 'shoes' }
// ...}Examples
Section titled “Examples”Sharing components with App Router
Section titled “Sharing components with App Router”useParams from next/navigation works in both the Pages Router and App Router. This allows you to create shared components that work in either context:
import { useParams } from 'next/navigation'
// This component works in both pages/ and app/export function Breadcrumb() { const params = useParams<{ slug: string }>()
if (!params) { // Fallback for Pages Router during pre-rendering return <nav>Home / ...</nav> }
return <nav>Home / {params.slug}</nav>}import { useParams } from 'next/navigation'
// This component works in both pages/ and app/export function Breadcrumb() { const params = useParams()
if (!params) { // Fallback for Pages Router during pre-rendering return <nav>Home / ...</nav> }
return <nav>Home / {params.slug}</nav>}Good to know: When using this component in the App Router,
useParamsnever returnsnull, so the fallback branch will not be rendered.
Version History
Section titled “Version History”| Version | Changes |
|---|---|
v13.3.0 | useParams introduced. |