url.searchParams
Exposes a URL's query string as a live URLSearchParams object that writes changes back to the URL.
url.searchParams- Added in Node.js v7.0.0, v6.13.0
Return value
URLSearchParamsThe URLSearchParams object representing the query parameters of the URL. The property is read-only, but the object it returns mutates the URL.
Errors
Assigning to url.searchParams itself is ignored in sloppy mode and throws a TypeError in strict mode; use the url.search setter to replace the whole query.
Every URL instance carries a searchParams object bound to its query string. The binding runs both ways: reading it reflects the current url.search, and mutating it — set, append, delete, sort — immediately re-serializes url.search and url.href.
When to reach for it
Use it whenever you are editing a query rather than building one from scratch: adding a pagination cursor to an incoming request URL, stripping tracking parameters before storing a link, or reading a single value out of a callback URL. It handles percent-encoding on both sides, so values containing &, = or spaces round-trip correctly without you touching encodeURIComponent.
What trips people up
The property is read-only. url.searchParams = new URLSearchParams(...) silently does nothing (or throws under 'use strict'). To replace the entire query, assign to url.search instead — which also swaps in a fresh set of params, invalidating any reference you were holding.
The other surprise is serialization: URLSearchParams uses application/x-www-form-urlencoded rules, so a space becomes +, not %20. Setting url.search by hand with %20 and then reading it back through searchParams will show + in href.
Example
When to use it
- Append a page or cursor parameter to an incoming request URL before proxying it
- Strip utm_* tracking parameters from links before saving them
- Read an OAuth code and state out of a redirect callback URL
- Sort parameters so two equivalent URLs produce identical cache keys
Frequently asked questions
How do I add a query parameter to an existing URL in Node?
Parse it with new URL() and call url.searchParams.set('key', 'value') — url.href updates immediately. Use append instead of set when the key may legitimately appear more than once.
Why can't I assign to url.searchParams?
The property is read-only by specification; only the object it returns is mutable. Replace the entire query with the url.search setter, for example url.search = new URLSearchParams({a: 1}).toString().
Why does my URL show + instead of %20 for spaces?
URLSearchParams serializes with form-urlencoding, where a space is +. Both forms decode back to a space on the server, but if a service insists on %20 you must build the query string yourself with encodeURIComponent.
More examples
Removing tracking parameters from a link
The keys() iterator is copied into an array first — deleting while iterating a live iterator skips entries. Only color=red survives, and href is rewritten without any manual string surgery.
const u = new URL('https://shop.example.com/p/42?utm_source=mail&utm_campaign=spring&color=red&utm_medium=cpc');
for (const key of [...u.searchParams.keys()]) {
if (key.startsWith('utm_')) u.searchParams.delete(key);
}
console.log(u.href);
console.log([...u.searchParams]);Replacing the whole query breaks the old reference
Assigning to url.search rebuilds the parameter list. The URL still reports the new query, and mutating the reference captured earlier no longer affects it — which is exactly why stale references cause silent no-op bugs.
const u = new URL('https://example.com/a?x=1');
const before = u.searchParams;
u.search = '?y=2&z=3';
console.log(u.href);
console.log('same object?', before === u.searchParams);
console.log('live object sees:', [...u.searchParams]);
before.set('x', '99');
console.log('after mutating the stale reference:', u.href);Values are encoded and decoded automatically
The literal & and = inside the value are escaped to %26 and %3D so they cannot break out of the parameter, and the space serializes as +. Reading the values back returns the original unencoded strings.
const u = new URL('https://example.com/api');
u.searchParams.set('filter', 'name=a&b');
u.searchParams.set('note', 'hello world');
console.log(u.href);
console.log(u.searchParams.get('filter'));
console.log(u.searchParams.get('note'));
Discussion