#How do I stop search params from being automatically converted to number?

26 messages ยท Page 1 of 1 (latest)

vale kiln
#

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.

window.location.href // 'http://localhost:3000?code=123'
new URL(window.location.href).searchParams.get('code') // '123' (string)

export const Route = createFileRoute('/')({
  validateSearch(search) {
    search.code // 123 (number)  
  }
})
twilit crystal
#

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 numbers

vale kiln
#

Yeah of course, just wanted to check whether this is expected behavior or not first

vale kiln
twilit crystal
#

thanks, you're right. Even the input to validateSearchalready has code as number

@modern hamlet 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?

#

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-L53

GitHub

๐Ÿค– 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

#

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.parse

but it does more parsing additionally

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.

vale kiln
#

Yeah I agree on the type. Would be much easier to access properties on it if it was Record<string, unknown>

tender axle
#

I agree. {} just means anything that's not null or undefined which is not correct likely

vale kiln
#

So for the parsing, are the docs wrong or the code? ๐Ÿ˜…

#

When doing this

parseSearch: parseSearchWith(JSON.parse),
stringifySearch: stringifySearchWith(JSON.stringify),

I'm getting a really weird result. The search param switches between number and string a couple of times on load.

#

I'll see if I can reproduce this in the stackblitz

twilit crystal
#

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 :/

vale kiln
#

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

modern hamlet
neat vector
#

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.