[RFC]: Type-Safe URL Search Params for useSearchParams
hook
#13713
onyedikachi23
started this conversation in
Proposals
Replies: 2 comments 5 replies
-
A few questions:
|
Beta Was this translation helpful? Give feedback.
5 replies
-
Without getting too deep in the weeds here, this proposal should be targeting the routes.ts file rather than another export bloating the surface API as @alexanderson1993 mentioned. This needs very careful consideration of locking in a validation library (or requiring one at all?) and should be typegen first.
|
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
RFC: Type-Safe URL Search Parameters for
useSearchParams
Last Edited: June 3, 2025
This proposal is made according to the guidelines provided here: GOVERNANCE.md - New Feature Process.
Edit Summary
useSearchParams
now accepts schema via options object;defineSearchParams
takes individual param schemas.searchParams
export renamed tosearchParamsSchema
for router internals.setParams
overwrites.typegen
to inferInfo.searchParams
directly from route schemas.Problem
useSearchParams
currently exposes the untypedURLSearchParams
API. This results in runtime errors, boilerplate, and poor developer experience due to a lack of compile-time safety, inconsistent with React Router's strong type support for path parameters and loader/action data.Motivation
To elevate
useSearchParams
to the same standard of type safety as other core React Router APIs. By integrating a standard schema-based approach for search params, we can:useSearchParams
with the library's existing type system.typegen
), seamless type consistency forloaders
andactions
, and overall API standardization, cannot be effectively achieved or maintained in user-land without significant boilerplate or breaking the "Routing and Data Focused" design principle.Proposed Solution: New
searchParamsSchema
Route Module Export & EnhanceduseSearchParams
HookWe propose introducing a new, optional
searchParamsSchema
export within route modules. This export would be an object returned by a React Router utility (e.g.,defineSearchParams
) that encapsulates individual schema definitions for each search parameter.react-router typegen
would process this to type the route'sInfo
object. Concurrently, theuseSearchParams
hook will be enhanced to accept an optional schema, providing typed state when a schema is provided, while maintaining backward compatibility by returning an untypedURLSearchParams
object when no schema is passed.New Utilities and Concepts
defineSearchParams
utility: A new function used to create search parameter schemas. It takes a plain object where each property's value is an individual schema definition (e.g.,z.string()
,z.number()
). These schemas can be used in route modules or directly with theuseSearchParams
hook.searchParamsSchema
export: A new, optional export from route modules. It holds the schema definition for that route's search parameters, created usingdefineSearchParams
. This export serves as the canonical source for internal router processes (likeloaders
/actions
) to parse and typeURLSearchParams
for their specific context.useSearchParams
hook: The existing hook is updated. It now optionally accepts asearchParamsSchema
object to provide type-safe access and updates to URL search parameters. If no schema is provided, it behaves as it currently does.Info.searchParams
type: A new property generated byreact-router typegen
within a route'sInfo
type, providing compile-time type safety for search parameters based on thesearchParamsSchema
export.null
. No errors are surfaced.Core Concepts
Dedicated
searchParamsSchema
Route Module Export:A new, optional
searchParamsSchema
export will be an object created by a React Router utility function, likedefineSearchParams({ param1: z.string(), param2: z.number() })
. This declares the canonical types and validation rules for URL search parameters pertinent to this specific route. This export is crucial for internal router processes (such asloaders
andactions
) to consistently parse and typeURLSearchParams
for their associated route's context.Internal Processing & Validation:
When a schema is provided to
useSearchParams
(or used by other router internals), React Router's runtime internally parses and validatesrequest.url.searchParams
against the provided schema.null
.setParams
, any existing same-named parameters are overwritten by data conforming to the writer's schema.Type Generation Integration:
react-router typegen
identifies and processes thesearchParamsSchema
export. It generates a correspondingsearchParams
property within the route'sInfo
type (e.g., in.react-router/types/app/routes/+types/products.ts
). This type will be based directly on the schema's inferred type (including potentialnull
orundefined
types based on schema defaults).Example generated type snippet within
Info
:Enhanced
useSearchParams
Hook:The
useSearchParams
hook is enhanced to:useSearchParams()
), it returns the current untypedURLSearchParams
object and updater.useSearchParams({ schema: mySchema })
), it returns a tuple where the first element (params
) is a strongly typed object based on the provided schema, and the second (setParams
) accepts an object conforming to that schema for type-safe updates.searchParamsSchema
exported by the current route module, or any other schema defined elsewhere in the application.Example Implementation
app/routes/products.tsx
:Advantages
useSearchParams()
calls continue to work unchanged.searchParamsSchema
export provides a canonical, typegen-discoverable schema for routes, crucial for consistent internal parsing inloaders
/actions
.Disadvantages / Trade-offs
useSearchParams
does not automatically infer thesearchParamsSchema
from the module context; it must be explicitly provided. This trade-off provides the flexibility for the hook to be used with any schema, not solely restricted to the route's module definition.Community Alternatives
The React ecosystem has developed solutions to address the lack of type-safe URL search parameters, which this proposal builds upon and aims to integrate natively.
nuqs: A dedicated, type-safe search params state manager for React. This proposal is heavily inspired by
nuqs
's declarative, parser-driven approach to managing URL state.Custom Hooks for Abstraction & Validation: A common pattern as described in an X post by Cory House involves creating custom React hooks that encapsulate
useSearchParams
, abstracting away the manual parsing, validation (e.g., with Zod), and serialization logic. An example of this approach is shown in the following snippet:This proposal aims to bring the core benefits of these patterns directly into
useSearchParams
for a more integrated and consistent first-party experience.Beta Was this translation helpful? Give feedback.
All reactions