47ng / nuqs

Type-safe search params state manager for React frameworks - Like useState, but stored in the URL query string.
https://nuqs.47ng.com
MIT License
4.86k stars 104 forks source link

Serializer is returning an empty string on default search params in v2 #715

Closed blechatellier closed 3 weeks ago

blechatellier commented 3 weeks ago

Context

What's your version of nuqs? nuqs@2.0.4

What framework are you using? ✅ Next.js (app router)

Which version of your framework are you using? next@15.0.1

Description

After upgrading to v2, the serializer returns an empty string when search params are using the default.

franky47 commented 3 weeks ago

That's a consequence of the option clearOnDefault changing from false to true by default in v2.

It's true that this might be counter-intuitive for the serializer, if one wants to create a link that does hardcode the defaults in the URL.

Unfortunately for now, the serializer does not accept global options, like useQueryStates, but it should if we want to support urlKeys as well. In the mean time, the alternative would be to pass the clearOnDefault: false to each parser in the object when configuring the serializer:

const serialize = createSerializer({
  foo: parseAsString.withOptions({ clearOnDefault: false }),
  bar: parseAsInteger.withOptions({ clearOnDefault: false })
})

I'll see what I can do to add global options support this week.

blechatellier commented 3 weeks ago

Thanks @franky47 - setting clearOnDefault to false indeed fix the issue. Somehow my next implementation doesn't re-render unless the params are hardcoded.

franky47 commented 3 weeks ago

Could you elaborate that last part? The useQueryState(s) hooks should follow the URL, and if a key isn't in the query string, return the default value if specified (or null otherwise).

blechatellier commented 3 weeks ago

I'm passing the serialize function directly to the <Link href={serialize(...)} /> next component. When the params are matching the defaults, it sets the link to an empty string, preventing the page to re-render.

kasperadk commented 3 weeks ago

@blechatellier Thank you for posting this! I was struggling with the same problem.

franky47 commented 3 weeks ago

I've added a fix for this in #720.

createSerializer now accepts a second argument where you can specify both clearOnDefault: false (it still defaults to true to mirror useQueryState(s)' behaviour) and a urlKeys map to shorten your query keys (same as for useQueryStates).

You can try it here:

pnpm add https://pkg.pr.new/nuqs@720
blechatellier commented 3 weeks ago

@franky47 awesome, cleaner this way.

franky47 commented 3 weeks ago

:tada: This issue has been resolved in version 2.1.0 :tada:

The release is available on:

blechatellier commented 3 weeks ago

Thanks @franky47 🙏