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
quickest-silver•2y 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 numbersunited-yellowOP•2y 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.tsxquickest-silver•2y ago
thanks, you're right. Even the input to
validateSearchalready 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?quickest-silver•2y 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
quickest-silver•2y 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.
quickest-silver•2y 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
united-yellowOP•2y ago
Yeah I agree on the type. Would be much easier to access properties on it if it was
Record<string, unknown>fair-rose•2y ago
I agree.
{} just means anything that's not null or undefined which is not correct likelyunited-yellowOP•2y ago
So for the parsing, are the docs wrong or the code? 😅
united-yellowOP•2y 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.

united-yellowOP•2y ago
I'll see if I can reproduce this in the stackblitz
united-yellowOP•2y 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
quickest-silver•2y 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
quickest-silver•2y 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 :/united-yellowOP•2y 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
robust-apricot•2y 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?vicious-gold•2y 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.