Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/router/framework/react/guide/path-params.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,12 @@ Optional parameters create flexible URL patterns:

- `/posts/{-$category}` matches both `/posts` and `/posts/tech`
- `/posts/{-$category}/{-$slug}` matches `/posts`, `/posts/tech`, and `/posts/tech/hello-world`
- `/posts/{-$category}/{-$slug}/list` matches `/posts/list`, `/posts/tech/list`, and `/posts/tech/hello-world/list`
- `/users/$id/{-$tab}` matches `/users/123` and `/users/123/settings`
- `/users/{-$category}/$id/{-$tab}` matches `/users/123`, `/users/admin/123` and `/users/admin/123/settings`
- `/users/{-$category}/$id/$slug/{-$tab}` matches `/users/123/slug`, `/users/admin/123/slug` and `/users/admin/123/slug/settings`
- `/users/{-$category}/$id/{-$tab}/$slug` matches `/users/123/slug`, `/users/admin/123/slug` and `/users/admin/123/settings/slug`
- `/users/{-$category}/$id/edit/{-$tab}` matches `/users/123/edit`, `/users/admin/123/edit`, `/users/123/edit/settings` and `/users/admin/123/edit/settings`

When an optional parameter is not present in the URL, its value will be `undefined` in your route handlers and components.

Expand Down
197 changes: 197 additions & 0 deletions e2e/react-router/basic-file-based/src/routeTree.gen.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute(
'/optional-params/consecutive/{-$id}/{-$slug}/$category/info',
)({
component: RouteComponent,
})

function RouteComponent() {
const params = Route.useParams()
return (
<>
<div data-testid="consecutive-heading">
Hello "/optional-params/consecutive/-$id/-$slug/$category/info"!
</div>
<div>
params:{' '}
<span data-testid="consecutive-id-slug-category-info-params">
{JSON.stringify(params)}
</span>
</div>
</>
)
}
262 changes: 262 additions & 0 deletions e2e/react-router/basic-file-based/src/routes/optional-params/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
import { Link, Outlet, createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/optional-params')({
component: RouteComponent,
})

function RouteComponent() {
return (
<div>
<h3 className="pb-2">optional path params</h3>
<ul className="grid mb-2">
<li>
<div>simple optional path param usage</div>
<div className="ml-5">
<ul>
<li>
<Link
data-testid="l-to-simple-index"
to="/optional-params/simple/{-$id}"
params={{
id: undefined,
}}
>
/optionals/simple
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-simple-id-index"
to="/optional-params/simple/{-$id}"
params={{ id: 'id' }}
>
/optionals/simple/id
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-simple-path"
to="/optional-params/simple/{-$id}/path"
params={{ id: undefined }}
>
/optionals/simple/path
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-simple-id-path"
to="/optional-params/simple/{-$id}/path"
params={{ id: 'id' }}
>
/optionals/simple/id/path
</Link>
</li>
</ul>
</div>
<hr />
</li>
<li>
<div>With path params and index page</div>
<div className="ml-5">
<ul>
<li>
<Link
data-testid="l-to-withIndex-category-index"
to="/optional-params/withIndex/{-$id}/$category"
params={{
id: undefined,
category: 'category',
}}
>
/optionals/withIndex/category
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-withIndex-id-category-index"
to="/optional-params/withIndex/{-$id}/$category"
params={{
id: 'id',
category: 'category',
}}
>
/optionals/withIndex/id/category
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-withIndex-category-path"
to="/optional-params/withIndex/{-$id}/$category/path"
params={{
id: undefined,
category: 'category',
}}
>
/optionals/withIndex/category/path
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-withIndex-id-category-path"
to="/optional-params/withIndex/{-$id}/$category/path"
params={{
id: 'id',
category: 'category',
}}
>
/optionals/withIndex/id/category/path
</Link>{' '}
</li>
</ul>
</div>
<hr />
</li>
<li>
<div>Consecutive path params</div>
<div className="ml-5">
<ul>
<li>
<Link
data-testid="l-to-consecutive-category-info"
to="/optional-params/consecutive/{-$id}/{-$slug}/$category/info"
params={{
id: undefined,
slug: undefined,
category: 'category',
}}
>
/optionals/consecutive/category/info
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-consecutive-id-category-info"
to="/optional-params/consecutive/{-$id}/{-$slug}/$category/info"
params={{ id: 'id', slug: undefined, category: 'category' }}
>
/optionals/consecutive/id1/category/info
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-consecutive-slug-category-info"
to="/optional-params/consecutive/{-$id}/{-$slug}/$category/info"
params={{ id: undefined, slug: 'slug', category: 'category' }}
>
/optionals/consecutive/slug/category/info
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-consecutive-id-slug-category-info"
to="/optional-params/consecutive/{-$id}/{-$slug}/$category/info"
params={{ id: 'id', slug: 'slug', category: 'category' }}
>
/optionals/consecutive/id1/slug/category/info
</Link>
</li>
</ul>
</div>
<hr />
</li>
<li>
<div>Required path in between optional and path params</div>
<div className="ml-5">
<ul>
<li>
<Link
data-testid="l-to-withRequiredInBetween-category"
to="/optional-params/withRequiredInBetween/{-$id}/$category/path/{-$slug}"
params={{
id: undefined,
slug: undefined,
category: 'category',
}}
>
/optionals/withRequiredInBetween/category/path
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-withRequiredInBetween-id-category"
to="/optional-params/withRequiredInBetween/{-$id}/$category/path/{-$slug}"
params={{ id: 'id', slug: undefined, category: 'category' }}
>
/optionals/withRequiredInBetween/id/category/path
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-withRequiredInBetween-category-slug"
to="/optional-params/withRequiredInBetween/{-$id}/$category/path/{-$slug}"
params={{ id: undefined, slug: 'slug', category: 'category' }}
>
/optionals/withRequiredInBetween/category/path/slug
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-withRequiredInBetween-id-category-slug"
to="/optional-params/withRequiredInBetween/{-$id}/$category/path/{-$slug}"
params={{ id: 'id', slug: 'slug', category: 'category' }}
>
/optionals/withRequiredInBetween/id/category/path/slug
</Link>
</li>
</ul>
</div>
<hr />
</li>
<li>
<div>Required Param in between optional path params</div>
<div className="ml-5">
<ul>
<li>
<Link
data-testid="l-to-withRequiredParam-category"
to="/optional-params/withRequiredParam/{-$id}/$category/{-$slug}/info"
params={{
id: undefined,
slug: undefined,
category: 'category',
}}
>
/optionals/withRequiredParam/category/info
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-withRequiredParam-id-category"
to="/optional-params/withRequiredParam/{-$id}/$category/{-$slug}/info"
params={{ id: 'id', slug: undefined, category: 'category' }}
>
/optionals/withRequiredParam/id1/category/info
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-withRequiredParam-category-slug"
to="/optional-params/withRequiredParam/{-$id}/$category/{-$slug}/info"
params={{ id: undefined, slug: 'slug', category: 'category' }}
>
/optionals/withRequiredParam/category/slug/info
</Link>{' '}
</li>
<li>
<Link
data-testid="l-to-withRequiredParam-id-category-slug"
to="/optional-params/withRequiredParam/{-$id}/$category/{-$slug}/info"
params={{ id: 'id', slug: 'slug', category: 'category' }}
>
/optionals/withRequiredParam/id1/category/slug/info
</Link>
</li>
</ul>
</div>
</li>
</ul>
<hr />
<Outlet />
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/optional-params/simple/{-$id}/')({
component: RouteComponent,
})

function RouteComponent() {
const params = Route.useParams()

return (
<div data-testid="simple-index-heading">
Hello "/optional-params/simple/-$id/"!
<span data-testid="simple-index-params">{JSON.stringify(params)}</span>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/optional-params/simple/{-$id}/path')({
component: RouteComponent,
})

function RouteComponent() {
const params = Route.useParams()
return (
<div data-testid="simple-path-heading">
Hello "/optional-params/simple/-$id/path"!
<span data-testid="simple-path-params">{JSON.stringify(params)}</span>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute(
'/optional-params/withIndex/{-$id}/$category/',
)({
component: RouteComponent,
})

function RouteComponent() {
const params = Route.useParams()
return (
<div data-testid="withIndex-index-heading">
Hello "/optional-params/withIndex/-$id/$category/"!
<span data-testid="withIndex-index-params">{JSON.stringify(params)}</span>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute(
'/optional-params/withIndex/{-$id}/$category/path/',
)({
component: RouteComponent,
})

function RouteComponent() {
const params = Route.useParams()
return (
<div data-testid="withIndex-path-heading">
Hello "/optional-params/withIndex/-$id/$category/path"!
<span data-testid="withIndex-path-params">{JSON.stringify(params)}</span>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute(
'/optional-params/withRequiredInBetween/{-$id}/$category/path/{-$slug}',
)({
component: RouteComponent,
})

function RouteComponent() {
const params = Route.useParams()

return (
<>
<div data-testid="withRequiredInBetween-heading">
Hello
"/optional-params/withRequiredInBetween/-$id/$category/path/$slug"!
</div>
<div>
params:{' '}
<span data-testid="withRequiredInBetween-id-category-path-slug-params">
{JSON.stringify(params)}
</span>
</div>
</>
)
}
Loading
Loading