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

Encode unsafe URI characters #925

Open
lesha1201 opened this issue Feb 24, 2025 · 4 comments
Open

Encode unsafe URI characters #925

lesha1201 opened this issue Feb 24, 2025 · 4 comments
Labels
bug Something isn't working

Comments

@lesha1201
Copy link

lesha1201 commented Feb 24, 2025

Currently, nuqs doesn't encode certain characters (e.g. [) in URI which might produce some issues between different environments.

For example, when Safari on iOS identifies [ or { symbol in URI, it automatically encodes whole search parameters even if some parts of it are already encoded. It can cause an issue when you copy a URL containing those characters from some browser and paste it to Safari on iOS. Consider such case

  1. User copies a URL https://test.com/?name=[тест. The most of browsers automatically encodes the copied URL and actually copy https://test.com/?name=[%D1%82%D0%B5%D1%81%D1%82 to the clipboard. Notice that it doesn't encode [ symbol.
  2. User opens that link (https://test.com/?name=[%D1%82%D0%B5%D1%81%D1%82) on Safari iOS.
  3. Safari sees [ character in search params and automatically encodes it (even though some content were already encoded): https://test.com/?name=[%D1%82%D0%B5%D1%81%D1%82 -> https://test.com/?name=%5B%25D1%2582%25D0%25B5%25D1%2581%25D1%2582.
  4. User sees [%D1%82%D0%B5%D1%81%D1%82 in UI instead of seeing [тест.

The issue becomes more apparent when you use parseAsJson (because it often produces [, { characters) and UTF-8 characters (e.g. website with non-latin language).

I don't know the actual logic on Safari iOS of encoding the URL. From my quick testing, it always does it if there is at least one [ or { character.

Context

2.4.0

What framework are you using?

  • ✅ Next.js (app router)

Which version of your framework are you using?

v15

Reproduction

I've created a minimal example which uses useQueryState (copied from nuqs docs) - https://codesandbox.io/p/devbox/9953r5

  1. Open https://9953r5-3000.csb.app/?name=[%D1%82%D0%B5%D1%81%D1%82 (this is the copied version of https://test.com/?name=[тест) on Safari iOS. Instead of having [тест in the input, it shows [%D1%82%D0%B5%D1%81%D1%82. But if you open it, for example, on Chrome or Firefox (not on iOS), then it works fine.
@lesha1201 lesha1201 added the bug Something isn't working label Feb 24, 2025
@franky47
Copy link
Member

Thanks, I can reproduce the issue when clicking the link (on iOS 18.3, Safari and Firefox, which is all WebKit under the hood), but not when copy/pasting it with the encoded values (https://9953r5-3000.csb.app/?name=[%D1%82%D0%B5%D1%81%D1%82).

I can't reproduce it on Safari on macOS however.

@lesha1201
Copy link
Author

@franky47

but not when copy/pasting it with the encoded values (https://9953r5-3000.csb.app/?name=[%D1%82%D0%B5%D1%81%D1%82)

Indeed. Then it's probably not related to WebKit but to something else on iOS. I've also noticed that it has that issue:

  1. in Chrome on iOS when using Copied URL suggestion in the search bar
  2. when pasting it to the searchbar in Arc browser.

@lesha1201
Copy link
Author

@franky47 I was trying to understand how search params should be encoded but there are a lot of uncertainties.

There is one standard which is quite outdated - https://datatracker.ietf.org/doc/html/rfc3986. But that standard doesn't provide details of how we should encode query component but instead provides a general guideline of how to encode all components. By that standard, we should encode all reserved characters (e.g. [).

There is also a new standard - https://url.spec.whatwg.org/, which provides more details of how certain components should be encoded. And by that standard we don't need to encode [ for query component (https://url.spec.whatwg.org/#query-percent-encode-set). But implementation of URLSearchParams uses application/x-www-form-urlencoded percent-encode set which has more character to encode (including [).

Taking all into account, I think it will be more safe to use the same set of code points that should be encoded as URLSearchParams has for now (or just use URLSearchParams for encoding) or at least give an option to opt-out from custom encoding behavior, since that's a native approach for encoding/decoding search params on the web.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants