diff --git a/doc/api/url.md b/doc/api/url.md index 6950c92f0980c8..3da8adbe8568d2 100644 --- a/doc/api/url.md +++ b/doc/api/url.md @@ -472,9 +472,27 @@ and [`url.format()`][] methods would produce. * {URLSearchParams} Gets the [`URLSearchParams`][] object representing the query parameters of the -URL. This property is read-only; to replace the entirety of query parameters of -the URL, use the [`url.search`][] setter. See [`URLSearchParams`][] -documentation for details. +URL. This property is read-only but the `URLSearchParams` object it provides +can be used to mutate the URL instance; to replace the entirety of query +parameters of the URL, use the [`url.search`][] setter. See +[`URLSearchParams`][] documentation for details. + +Use care when using `.searchParams` to modify the `URL` because, +per the WHATWG specification, the `URLSearchParams` object uses +different rules to determine which characters to percent-encode. For +instance, the `URL` object will not percent encode the ASCII tilde (`~`) +character, while `URLSearchParams` will always encode it: + +```js +const myUrl = new URL('https://example.org/abc?foo=~bar'); + +console.log(myUrl.search); // prints ?foo=~bar + +// Modify the URL via searchParams... +myUrl.searchParams.sort(); + +console.log(myUrl.search); // prints ?foo=%7Ebar +``` #### `url.username` diff --git a/test/parallel/test-whatwg-url-custom-searchparams-stringifier.js b/test/parallel/test-whatwg-url-custom-searchparams-stringifier.js index 1fe936f5e293ab..35307fa914975a 100644 --- a/test/parallel/test-whatwg-url-custom-searchparams-stringifier.js +++ b/test/parallel/test-whatwg-url-custom-searchparams-stringifier.js @@ -16,3 +16,12 @@ const URLSearchParams = require('url').URLSearchParams; message: 'Value of "this" must be of type URLSearchParams' }); } + +// The URLSearchParams stringifier mutates the base URL using +// different percent-encoding rules than the URL itself. +{ + const myUrl = new URL('https://example.org?foo=~bar'); + assert.strictEqual(myUrl.search, '?foo=~bar'); + myUrl.searchParams.sort(); + assert.strictEqual(myUrl.search, '?foo=%7Ebar'); +}