route.validateSearch
入力を TSearchSchemaInput & SearchSchemaInput に「タグ付け」すると、<Link/> や navigate() で使う 入力型(オプショナル等)と、実際にルート内で参照される 確定型 を分けられるのがポイント。
zodやvalibotなども使える
例
code:tsx
export const Route = createFileRoute('/shop/products')({
validateSearch: (search: Record<string, unknown>): ProductSearch => ({
page: Number(search?.page ?? 1),
filter: (search.filter as string) || '',
sort: (search.sort as ProductSearchSortOptions) || 'newest',
}),
})
こうすることで:
URL パラメータが不正でも安全に fallback
型 (ProductSearch) が保証される
子ルートでも同じ型情報が継承される
validation libraryも使える
Effectの例
code:ts
import { createFileRoute } from '@tanstack/react-router'
import { Schema as S } from 'effect'
const productSearchSchema = S.standardSchemaV1(
S.Struct({
page: S.NumberFromString.pipe(
S.optional,
S.withDefaults({
constructor: () => 1,
decoding: () => 1,
}),
),
filter: S.String.pipe(
S.optional,
S.withDefaults({
constructor: () => '',
decoding: () => '',
}),
),
sort: S.Literal('newest', 'oldest', 'price').pipe(
S.optional,
S.withDefaults({
constructor: () => 'newest' as const,
decoding: () => 'newest' as const,
}),
),
}),
)
export const Route = createFileRoute('/shop/products/')({
validateSearch: productSearchSchema,
})