Closed Carlwirkus closed 1 month ago
This problem occurs because of the way URL encoding and decoding works.
The URL http://localhost:3000?foo=1%26bar=2 encodes the ampersand (&) as %26, so it gets interpreted as part of the value of the foo parameter instead of as a delimiter between query parameters.
If you want to get result like searchParams: { foo: '1', bar: '2' } }
, please use & instead of %26.
http://localhost:3000?foo=1&bar=2
Yes, would it not be common sense for these to be decoded?
In my case, our email marketing platform appends UTM parameters with percent encoding. As the router does not decoded the URL, the links are broken.
Could you provide the code that get data from this URL?
I mean the code that decoded http://localhost:3000?foo=1%26bar=2
to searchParams: { foo: '1&bar=2' } }
Unfortunately, this is just default behaviour. If you JSON.stringify(props)
you'll see the searchParams: { foo: '1&bar=2' } }
https://github.com/Carlwirkus/next-searchparams/blob/main/app/page.tsx
Try to decode the parameters manually.
export default function Home() {
const [params, setParams] = useState({});
const router = useRouter();
useEffect(() => {
const { query } = router;
const decodedParams = {};
for (const key in query) {
if (query.hasOwnProperty(key)) {
decodedParams[key] = decodeURIComponent(query[key]);
}
}
setParams(decodedParams);
}, [router.query]);
...
}
Thanks, I understand there are ways to manually decode searchParams from the URL.
I feel like either: this should be decoded by default or Next should have some way add/change the decoding.
Hi, as per spec &
is a special character which is used to separate the query parameters.
Source, The characters ";", "/", "?", ":", "@", "=" and "&" are the characters which may be reserved for special meaning within a scheme
With that being said, we can see how this is implemented into the Web APIs:
// run this in your own browser console
new URL("http://localhost:3000?foo=1%26bar=2").searchParams.get("foo")
We can see that it prints back: '1&bar=2'
That's the value of foo
, as you define it, and compliant to spec. What is Next.js supposed to do for you here. If they had some behavior changing the encoding, there'd be people complaining that it doesn't respect the spec.
How did you get k: v, i get empty
Hi, as per spec
&
is a special character which is used to separate the query parameters.Source, The characters ";", "/", "?", ":", "@", "=" and "&" are the characters which may be reserved for special meaning within a scheme
- https://www.rfc-editor.org/rfc/rfc3986 additional resource
With that being said, we can see how this is implemented into the Web APIs:
// run this in your own browser console new URL("http://localhost:3000?foo=1%26bar=2").searchParams.get("foo")
We can see that it prints back:
'1&bar=2'
That's the value of
foo
, as you define it, and compliant to spec. What is Next.js supposed to do for you here. If they had some behavior changing the encoding, there'd be people complaining that it doesn't respect the spec.
Thanks, so the issue here is that the marketing email provider (Mailchimp) is encoding URLs incorrectly.
I think It'd be nice to have a mechanism to decode the URL before they are passed to the URLSearchParams but maybe that's attacking the problem from the wrong side.
This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.
Link to the code that reproduces this issue
https://github.com/Carlwirkus/next-searchparams
To Reproduce
Start a new application Navigate to
http://localhost:3000?foo=1%26bar=2
Current vs. Expected behavior
Current
searchParams: { foo: '1&bar=2' } }
Expected
searchParams: { foo: '1', bar: '2' } }
Provide environment information
Which area(s) are affected? (Select all that apply)
Navigation
Which stage(s) are affected? (Select all that apply)
next dev (local), next build (local), next start (local), Vercel (Deployed), Other (Deployed)
Additional context
URLs are not decoded before they are parsed by URLSearchParams. This is not the expected behaviour.