sst / open-next

Open source Next.js serverless adapter
https://open-next.js.org
MIT License
3.73k stars 112 forks source link

multi-value query parameters behave differently when using open-next #319

Closed thoaltmann closed 7 months ago

thoaltmann commented 7 months ago

We have a few pages and API-routes in our application that use multi-value query parameters with the same key and after updating open-next, this doesn't work as expected anymore.

The NextJS useSearchParams-hook and request.nextUrl.searchParams in e.g. API routes convert query parameters to an array when they are in the form of ?paramKey=value1&paramKey=value2

// API route
request.nextUrl.searchParams.getAll("paramKey") // => ["value1", "value2"]

// hook
const searchParams = useSearchParams();
searchParams.getAll("paramKey") // => ["value1", "value2"]

However, due to probably https://github.com/sst/open-next/blob/main/packages/open-next/src/adapters/routing/middleware.ts#L67 such query parameters are now transformed to ?paramKey=value1,value2. With this change, multiple query parameters with the same key are no longer regarded as arrays:

// API route
request.nextUrl.searchParams.getAll("paramKey") // => ["value1,value2"]

// hook
const searchParams = useSearchParams();
searchParams.getAll("paramKey") // => ["value1,value2"]

Building and running the Next-app locally works as expected, but as soon as it's deployed, the rewriting of the querystring breaks our application.

khuezy commented 7 months ago

Hi thanks for the report. CC: @pbaire We had this discussion I think in https://github.com/sst/open-next/pull/281#discussion_r1360901658

thoaltmann commented 7 months ago

Hi, thanks for the link!

I've experimented with how "plain" next handles URLs in this form, like "?name=Bob&name=Alice," and it appears that it simply combines the values by appending them. Specifically, within the page, I receive a single string value, 'BobAlice' .

I just tested this in a stackblitz and while it's true that when you use <div>{params.getAll("name")}</div> in JSX directly, the printed value is just the concatenated string "AliceBob", that's just due to how react renders arrays. If you render <div>{["Alice", "Bob"]}</div> the result is the same, but the underlying object is still an array, so Next does support this feature

khuezy commented 7 months ago

@thoaltmann can you put up a PR?

thoaltmann commented 7 months ago

@khuezy I can certainly try, I'll start setting up open-next locally tomorrow morning and I'll see how far I can get 😄

conico974 commented 7 months ago

Fixed in https://github.com/sst/open-next/pull/320