How do I stop search params from being automatically converted to number?
In validateSearch, a search param that's alphanumeric is coming in as a number if there are no letters in the value. Is this expected? My input validation with Valibot rejects it because of that.
I really wouldn't expect the router to do anything with the value before validateSearch runs.
For example, using URL the value is parsed as a string, not number.
17 Replies
molecular-blue•16mo ago
can you show a reproduction by forking one of our examples please?
I remember having to use
z.coerce
explicitly because I'm getting in strings for numbersstormy-goldOP•16mo ago
Yeah of course, just wanted to check whether this is expected behavior or not first
Here's a repro, although using
useSearch
which gives the same result
https://stackblitz.com/edit/github-8tcva3?file=src%2Froutes%2Findex.tsxmolecular-blue•16mo ago
thanks, you're right. Even the input to
validateSearch
already has code
as number
@Manuel Schiller is taht on purpose? Tbh I don't think so.
Also, for validateSearch
, the input is typed as {}
. In the docs, we manually put a type there as Record<string, unknown>
. Why isn't that the default?molecular-blue•16mo ago
aah okay I got it. It seems like our defaultSearch parsing uses
qss
and that converts strings to numbers, and booleans as well
https://github.com/TanStack/router/blob/ee5bb089f2336dc0f411149360f996d04b615ef9/packages/react-router/src/qss.ts#L47-L53GitHub
router/packages/react-router/src/qss.ts at ee5bb089f2336dc0f4111493...
🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering. - TanStack/router
molecular-blue•16mo ago
it can be customized: https://tanstack.com/router/latest/docs/framework/react/guide/custom-search-param-serialization#custom-search-param-serialization
I think docs aren't fully up to date because it mentions:
By default, TanStack Router parses and serializes your search params automatically using JSON.stringify/JSON.parsebut it does more parsing additionally
Custom Search Param Serialization | TanStack Router React Docs
TODO This portion of documentation is currently under construction
By default, TanStack Router parses and serializes your search params automatically using JSON.stringify/JSON.parse. Depending on your needs though, you may want to customize the serialization process.
molecular-blue•16mo ago
I still think that default type should be
Record<string, unknown>
: https://github.com/TanStack/router/blob/6c1d831b2747222d5cbbbe4b61df3308bd05a09b/packages/react-router/src/route.ts#L114
thoughts @Chris Horobin ?GitHub
router/packages/react-router/src/route.ts at 6c1d831b2747222d5cbbbe...
🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering. - TanStack/router
stormy-goldOP•16mo ago
Yeah I agree on the type. Would be much easier to access properties on it if it was
Record<string, unknown>
sunny-green•16mo ago
I agree.
{}
just means anything that's not null
or undefined
which is not correct likelystormy-goldOP•16mo ago
So for the parsing, are the docs wrong or the code? 😅
stormy-goldOP•16mo ago
When doing this
I'm getting a really weird result. The search param switches between number and string a couple of times on load.

stormy-goldOP•16mo ago
I'll see if I can reproduce this in the stackblitz
stormy-goldOP•16mo ago
Yeah
parseSearch/stringifySearch
does not seem to help here. It's still number https://stackblitz.com/edit/github-8tcva3-d7fvbp?file=src%2Fmain.tsxJakob Norlin
StackBlitz
Router Quickstart File Based Example (forked) - StackBlitz
Run official live example code for Router Quickstart File Based, created by Tanstack on StackBlitz
molecular-blue•16mo ago
oh, the call to
decode
is hardcoded:
https://github.com/TanStack/router/blob/41391cdd4a41ea5618b060e8a9437fbd83781719/packages/react-router/src/searchParams.ts#L16GitHub
router/packages/react-router/src/searchParams.ts at 41391cdd4a41ea5...
🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering. - TanStack/router
molecular-blue•16mo ago
and then the
parser
is run on every element
so it seems like you'll get boolean for true/false, number for number and string for everything else
could be a feature 😂
pathParams are different though - they are always a string. Not sure if that difference is a good thing :/stormy-goldOP•16mo ago
No honestly I would expect to always get strings back as a default
Luckily I tested with a numeric string to start off, but otherwise I would have probably pushed to prod a broken implementation, since we do schema validation in validateSearch which would fail on some values
adverse-sapphire•16mo ago
@Tanner Linsley do we really want to "pre-parse" search params into "best fitting" types prior to
validateSearch
?
Or should we default to strings?jolly-crimson•16mo ago
Not everyone will put the effort into validation. This is still better than the default experience imo.
We have to do some level of pre parsing to go from Record of string,string to JSON
Validation relies on json.
And there is a difference between storing a string/number/bool in the URL. That difference has just never been formalized before.