Returns URL parameters for the focused route, including dynamic segments and query string values.
This hook only updates when the route using it is focused, making it ideal for stack navigators where pushed screens shouldn’t react to parameter changes in other screens.
import { useParams } from 'one'
// Route: app/posts/[id].tsx
// URL: /posts/123?sort=date
export default function PostPage() {
const { id, sort } = useParams()
// id = '123', sort = 'date'
return <Text>Post {id}, sorted by {sort}</Text>
}
createRoute (Recommended)The best way to get fully typed params is with the createRoute helper:
import { createRoute } from 'one'
const route = createRoute<'/posts/[id]'>()
export default function PostPage() {
const { id } = route.useParams()
// id is automatically typed as string!
return <Text>Post {id}</Text>
}
Enable auto-generation in your vite config to have this inserted automatically:
// vite.config.ts
one({
router: {
experimental: {
typedRoutesGeneration: 'runtime', // auto-inserts createRoute
},
},
})
See Typed Routes for full setup details.
You can also type params manually:
export default function PostPage() {
const { id, sort } = useParams<{
id: string
sort?: 'date' | 'title'
}>()
return <Text>Post {id}</Text>
}
For catch-all routes like [...slug].tsx, params are returned as arrays:
// Route: app/docs/[...slug].tsx
// URL: /docs/api/hooks/useParams
export default function DocsPage() {
const { slug } = useParams<{ slug: string[] }>()
// slug = ['api', 'hooks', 'useParams']
return <Text>{slug.join(' / ')}</Text>
}
Parameters are automatically URL-decoded:
// URL: /search?q=hello%20world
const { q } = useParams()
// q = 'hello world' (decoded)
| Hook | Updates when… | Best for |
|---|---|---|
useParams | Route is focused | Most components |
useActiveParams | Any route changes | Analytics, global UI |
In a stack navigator, if you push a new screen, useParams in the previous screen won’t update. Use useActiveParams if you need global parameter updates.
Edit this page on GitHub.