Skip to main content

useRouter

ts
import { useRouter } from 'solito/router'
ts
import { useRouter } from 'solito/router'

This hook lets you navigate from one screen to another across platforms, using nothing but URLs and Next.js Url objects.

Usage

tsx
const { push, replace, back, parseNextPath } = useRouter()
 
const onPress = () => {
push('/')
}
const onGoBack = () => {
back()
}
tsx
const { push, replace, back, parseNextPath } = useRouter()
 
const onPress = () => {
push('/')
}
const onGoBack = () => {
back()
}

Returns

push

Follows the exact same API as push returned by Next.js useRouter hook.

Basic example

tsx
const { push } = useRouter()
 
const onOpenArtist = () => {
push('/artists/drake')
 
// or, you can do:
push({
pathname: '/artists/[slug]',
query: {
slug: 'drake',
},
})
}
tsx
const { push } = useRouter()
 
const onOpenArtist = () => {
push('/artists/drake')
 
// or, you can do:
push({
pathname: '/artists/[slug]',
query: {
slug: 'drake',
},
})
}

Passing query parameters

Use the query object to pass any query parameters to the next screen.

tsx
const { push } = useRouter()
 
const onOpenArtist = () => {
push({
pathname: '/artists/drake',
query: {
initialOfferAmount: 500000,
},
})
}
tsx
const { push } = useRouter()
 
const onOpenArtist = () => {
push({
pathname: '/artists/drake',
query: {
initialOfferAmount: 500000,
},
})
}

solito will automatically stringify this into a URL for you on Native, making it easy for React Navigation.

replace

Just like push(), this follows the exact same API as Next.js useRouter().replace.

It takes the exact same arguments as push.

tsx
const { replace } = useRouter()
 
const onOpenArtist = () => {
replace({
pathname: '/artists/drake',
query: {
initialOfferAmount: 500000,
},
})
}
tsx
const { replace } = useRouter()
 
const onOpenArtist = () => {
replace({
pathname: '/artists/drake',
query: {
initialOfferAmount: 500000,
},
})
}

Stack Replace on Native

Solito v2 introduces a new nativeBehavior option in the router.replace() function to let you use a stack replacement action on native navigators:

ts
import { useRouter } from 'solito/router'
export function Home() {
const router = useRouter()
const openArtists = () => {
replace('/artists', undefined, {
experimental: {
nativeBehavior: 'stack-replace',
isNestedNavigator: true,
},
})
}
// ...
}
ts
import { useRouter } from 'solito/router'
export function Home() {
const router = useRouter()
const openArtists = () => {
replace('/artists', undefined, {
experimental: {
nativeBehavior: 'stack-replace',
isNestedNavigator: true,
},
})
}
// ...
}

By passing nativeBehavior: 'stack-replace', you tell Solito to re-write your navigation action with StackActions.replace(). The isNestedNavigator property is an important way to indicate to Solito that your stack is nested inside of another navigator, such as tabs. Chances are, this property will always be true.

You can also use this functionality on the Link and TextLink components when replace is set to true:

tsx
<Link
href="/artists"
replace
experimental={{
nativeBehavior: 'stack-replace',
isNestedNavigator: true,
}}
/>
tsx
<Link
href="/artists"
replace
experimental={{
nativeBehavior: 'stack-replace',
isNestedNavigator: true,
}}
/>

For now, this feature will live behind the experimental flag.

parseNextPath

This function is used under the hood by push and replace to turn a Next.js Url object (or string) into a valid URL string. It's exposed in case you're doing something special.

It takes a Next.js Url object (or a string) and returns a stringified URL.

It's useful if you want to provide stable keys to lists of URLs, for instance.

API

ts
parseNextPath(url: string | Url): string
ts
parseNextPath(url: string | Url): string
ts
const path = parseNextPath({
pathname: '/artists',
})
ts
const path = parseNextPath({
pathname: '/artists',
})

Arguments

It has a single argument, which is either a string or a Url object. A Url object is the same as the first argument for push.

Returns

string

Usage

Imagine this example:

ts
const { parseNextPath } = useRouter()
 
const href = parseNextPath({
pathname: '/artists/[slug]',
query: {
slug: 'drake',
},
})
ts
const { parseNextPath } = useRouter()
 
const href = parseNextPath({
pathname: '/artists/[slug]',
query: {
slug: 'drake',
},
})

Here, href will become /artists/drake.

If you add other query parameters, they will be added to the end of the URL:

ts
const { parseNextPath } = useRouter()
 
const href = parseNextPath({
pathname: '/artists/[slug]',
query: {
slug: 'drake',
initialOfferAmount: 500_000,
},
})
ts
const { parseNextPath } = useRouter()
 
const href = parseNextPath({
pathname: '/artists/[slug]',
query: {
slug: 'drake',
initialOfferAmount: 500_000,
},
})

In this case, href is /artists/drake?initialOfferAmount=500000.

Basic example

tsx
const { parseNextPath } = useRouter()
 
const list = artists.map((artist) => {
const href = parseNextPath({
pathname: '/artists/[slug]',
query: {
slug: artist.slug,
},
})
 
return <Artist href={href} key={artist.slug} />
})
tsx
const { parseNextPath } = useRouter()
 
const list = artists.map((artist) => {
const href = parseNextPath({
pathname: '/artists/[slug]',
query: {
slug: artist.slug,
},
})
 
return <Artist href={href} key={artist.slug} />
})