Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query string formatting is odd? #1

Open
valorieschwartzdev opened this issue Mar 29, 2023 · 9 comments
Open

Query string formatting is odd? #1

valorieschwartzdev opened this issue Mar 29, 2023 · 9 comments

Comments

@valorieschwartzdev
Copy link

valorieschwartzdev commented Mar 29, 2023

My app has a very simple usage of this library where it stores the "search" query from a search box.

The store is set up like this:

const useShopStore = create<State>(
  querystring(
    (set) => ({
      query: "",
      items: undefined,
      fetchItems: async search => {
        set(() => ({ items: undefined, query: search?.query }))
        const inventory = await storeService.getItems(search);
        set(() => ({ items: inventory.items }))
      },
    }),
    {
      select(_: string) {
        return {
          query: true
        }
      }
    }))

It works, but the formatting of the query string in the address bar looks very odd. The resulting url is: http://localhost:3000/shop?$=query=some%20search%20query;;

I believe the proper formatting would be: http://localhost:3000/shop?query=some%20search%20query

Is this an error in the library or something that is configurable? Thanks in advance.

@nitedani
Copy link
Owner

nitedani commented Mar 29, 2023

This is by design. The readability and shortness of the generated querystring was important when I implemented this, but I also wanted to avoid breaking existing library/user code. The querystring middleware takes control of the addressbar of your browser and stores nested object structures in it serialized to a custom format. This format is not compatible with other libraries/user code. I wanted to minimize the number of issues/undefined behavior this would cause, for this reason the middleware stores all of the data in one single search parameter(by default $, this can be changed using the key prop). This way the middleware knows which part of the query string it has control over and it ignores the rest of it, so it wouldn't break existing code.

But you are right ideally the query string would look like your example. I will experiment with this and try to add a standalone: true setting, that would make it work like in your example.

@valorieschwartzdev
Copy link
Author

Yeah that makes sense. I 100% approve of the idea to make it compatible with other libraries, but having the option to turn that off and use a cleaner format would be nice. Thanks!

@mdwitr0
Copy link

mdwitr0 commented Aug 30, 2023

Seconded, I too would like to see openapi formatted parameters so nextjs can work with them in server mode.

Right now I get them in this format :(

http://localhost:3001/popular?$=params$genres@=thriller&=detective;&countries@=Russia&=USA;;

next search params response:

 {
   '$': 'params$genres@=thriller',
   '': [ 'detective;', 'USA;;' ],
   'countries@': 'Russia'
 }

@leoncvlt
Copy link

+1 for the standalone argument, would be nice for the sake of a prettier / more human-readable URL in apps where this library is the only entity manipulating query params.

@nitedani
Copy link
Owner

nitedani commented Dec 3, 2023

http://localhost:3001/popular?$=params$genres@=thriller&=detective;&countries@=Russia&=USA;;

The parameters should be accessible from the store, on server-side. You can use the url option to provide the request url server-side. Then, the values will be set in the store, even server-side. https://github.com/nitedani/zustand-querystring/blob/main/examples/next/src/store.tsx

@wingy3181
Copy link
Contributor

wingy3181 commented Dec 7, 2023

Yep that worked on the server-side

Using the following

export default function ExampleRSCPage({ searchParams }: {
  searchParams?: { [key: string]: string | string[] | undefined };
}) {

  const store = createStore({ url: `?${new URLSearchParams(searchParams).toString()}` });
  
  const {
    count,
    ticks,
    someNestedState: { nestedCount, incrementNestedCount, hello, setHello },
  } = store.getState();

 return (
   <insert jsx using above)
)

Created a PR to show this as part of the examples
#7

@nitedani
Copy link
Owner

nitedani commented Aug 8, 2024

Released https://github.com/nitedani/zustand-querystring/releases/tag/v0.1.0
What do you think about the change?

@ck-euan
Copy link

ck-euan commented Aug 23, 2024

@nitedani Is there a way to use the old readable style in the latest version?

@nitedani
Copy link
Owner

nitedani commented Aug 23, 2024

@ck-euan Not yet. I have an idea: making the encoding separate from the core logic, allowing users to provide their own encoder/decoder in the options. The library would also export the old encoder under zustand-querystring/encoding/urlon
#12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants