• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# URL
2
3<!--introduced_in=v0.10.0-->
4
5> Stability: 2 - Stable
6
7<!-- source_link=lib/url.js -->
8
9The `node:url` module provides utilities for URL resolution and parsing. It can
10be accessed using:
11
12```mjs
13import url from 'node:url';
14```
15
16```cjs
17const url = require('node:url');
18```
19
20## URL strings and URL objects
21
22A URL string is a structured string containing multiple meaningful components.
23When parsed, a URL object is returned containing properties for each of these
24components.
25
26The `node:url` module provides two APIs for working with URLs: a legacy API that
27is Node.js specific, and a newer API that implements the same
28[WHATWG URL Standard][] used by web browsers.
29
30A comparison between the WHATWG and legacy APIs is provided below. Above the URL
31`'https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash'`, properties
32of an object returned by the legacy `url.parse()` are shown. Below it are
33properties of a WHATWG `URL` object.
34
35WHATWG URL's `origin` property includes `protocol` and `host`, but not
36`username` or `password`.
37
38```text
39┌────────────────────────────────────────────────────────────────────────────────────────────────┐
40│                                              href                                              │
41├──────────┬──┬─────────────────────┬────────────────────────┬───────────────────────────┬───────┤
42│ protocol │  │        auth         │          host          │           path            │ hash  │
43│          │  │                     ├─────────────────┬──────┼──────────┬────────────────┤       │
44│          │  │                     │    hostname     │ port │ pathname │     search     │       │
45│          │  │                     │                 │      │          ├─┬──────────────┤       │
46│          │  │                     │                 │      │          │ │    query     │       │
47"  https:   //    user   :   pass   @ sub.example.com : 8080   /p/a/t/h  ?  query=string   #hash "
48│          │  │          │          │    hostname     │ port │          │                │       │
49│          │  │          │          ├─────────────────┴──────┤          │                │       │
50│ protocol │  │ username │ password │          host          │          │                │       │
51├──────────┴──┼──────────┴──────────┼────────────────────────┤          │                │       │
52│   origin    │                     │         origin         │ pathname │     search     │ hash  │
53├─────────────┴─────────────────────┴────────────────────────┴──────────┴────────────────┴───────┤
54│                                              href                                              │
55└────────────────────────────────────────────────────────────────────────────────────────────────┘
56(All spaces in the "" line should be ignored. They are purely for formatting.)
57```
58
59Parsing the URL string using the WHATWG API:
60
61```js
62const myURL =
63  new URL('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');
64```
65
66Parsing the URL string using the legacy API:
67
68```mjs
69import url from 'node:url';
70const myURL =
71  url.parse('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');
72```
73
74```cjs
75const url = require('node:url');
76const myURL =
77  url.parse('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');
78```
79
80### Constructing a URL from component parts and getting the constructed string
81
82It is possible to construct a WHATWG URL from component parts using either the
83property setters or a template literal string:
84
85```js
86const myURL = new URL('https://example.org');
87myURL.pathname = '/a/b/c';
88myURL.search = '?d=e';
89myURL.hash = '#fgh';
90```
91
92```js
93const pathname = '/a/b/c';
94const search = '?d=e';
95const hash = '#fgh';
96const myURL = new URL(`https://example.org${pathname}${search}${hash}`);
97```
98
99To get the constructed URL string, use the `href` property accessor:
100
101```js
102console.log(myURL.href);
103```
104
105## The WHATWG URL API
106
107### Class: `URL`
108
109<!-- YAML
110added:
111  - v7.0.0
112  - v6.13.0
113changes:
114  - version: v10.0.0
115    pr-url: https://github.com/nodejs/node/pull/18281
116    description: The class is now available on the global object.
117-->
118
119Browser-compatible `URL` class, implemented by following the WHATWG URL
120Standard. [Examples of parsed URLs][] may be found in the Standard itself.
121The `URL` class is also available on the global object.
122
123In accordance with browser conventions, all properties of `URL` objects
124are implemented as getters and setters on the class prototype, rather than as
125data properties on the object itself. Thus, unlike [legacy `urlObject`][]s,
126using the `delete` keyword on any properties of `URL` objects (e.g. `delete
127myURL.protocol`, `delete myURL.pathname`, etc) has no effect but will still
128return `true`.
129
130#### `new URL(input[, base])`
131
132<!--
133changes:
134  - version: v18.17.0
135    pr-url: https://github.com/nodejs/node/pull/47339
136    description: ICU requirement is removed.
137-->
138
139* `input` {string} The absolute or relative input URL to parse. If `input`
140  is relative, then `base` is required. If `input` is absolute, the `base`
141  is ignored. If `input` is not a string, it is [converted to a string][] first.
142* `base` {string} The base URL to resolve against if the `input` is not
143  absolute. If `base` is not a string, it is [converted to a string][] first.
144
145Creates a new `URL` object by parsing the `input` relative to the `base`. If
146`base` is passed as a string, it will be parsed equivalent to `new URL(base)`.
147
148```js
149const myURL = new URL('/foo', 'https://example.org/');
150// https://example.org/foo
151```
152
153The URL constructor is accessible as a property on the global object.
154It can also be imported from the built-in url module:
155
156```mjs
157import { URL } from 'node:url';
158console.log(URL === globalThis.URL); // Prints 'true'.
159```
160
161```cjs
162console.log(URL === require('node:url').URL); // Prints 'true'.
163```
164
165A `TypeError` will be thrown if the `input` or `base` are not valid URLs. Note
166that an effort will be made to coerce the given values into strings. For
167instance:
168
169```js
170const myURL = new URL({ toString: () => 'https://example.org/' });
171// https://example.org/
172```
173
174Unicode characters appearing within the host name of `input` will be
175automatically converted to ASCII using the [Punycode][] algorithm.
176
177```js
178const myURL = new URL('https://測試');
179// https://xn--g6w251d/
180```
181
182In cases where it is not known in advance if `input` is an absolute URL
183and a `base` is provided, it is advised to validate that the `origin` of
184the `URL` object is what is expected.
185
186```js
187let myURL = new URL('http://Example.com/', 'https://example.org/');
188// http://example.com/
189
190myURL = new URL('https://Example.com/', 'https://example.org/');
191// https://example.com/
192
193myURL = new URL('foo://Example.com/', 'https://example.org/');
194// foo://Example.com/
195
196myURL = new URL('http:Example.com/', 'https://example.org/');
197// http://example.com/
198
199myURL = new URL('https:Example.com/', 'https://example.org/');
200// https://example.org/Example.com/
201
202myURL = new URL('foo:Example.com/', 'https://example.org/');
203// foo:Example.com/
204```
205
206#### `url.hash`
207
208* {string}
209
210Gets and sets the fragment portion of the URL.
211
212```js
213const myURL = new URL('https://example.org/foo#bar');
214console.log(myURL.hash);
215// Prints #bar
216
217myURL.hash = 'baz';
218console.log(myURL.href);
219// Prints https://example.org/foo#baz
220```
221
222Invalid URL characters included in the value assigned to the `hash` property
223are [percent-encoded][]. The selection of which characters to
224percent-encode may vary somewhat from what the [`url.parse()`][] and
225[`url.format()`][] methods would produce.
226
227#### `url.host`
228
229* {string}
230
231Gets and sets the host portion of the URL.
232
233```js
234const myURL = new URL('https://example.org:81/foo');
235console.log(myURL.host);
236// Prints example.org:81
237
238myURL.host = 'example.com:82';
239console.log(myURL.href);
240// Prints https://example.com:82/foo
241```
242
243Invalid host values assigned to the `host` property are ignored.
244
245#### `url.hostname`
246
247* {string}
248
249Gets and sets the host name portion of the URL. The key difference between
250`url.host` and `url.hostname` is that `url.hostname` does _not_ include the
251port.
252
253```js
254const myURL = new URL('https://example.org:81/foo');
255console.log(myURL.hostname);
256// Prints example.org
257
258// Setting the hostname does not change the port
259myURL.hostname = 'example.com';
260console.log(myURL.href);
261// Prints https://example.com:81/foo
262
263// Use myURL.host to change the hostname and port
264myURL.host = 'example.org:82';
265console.log(myURL.href);
266// Prints https://example.org:82/foo
267```
268
269Invalid host name values assigned to the `hostname` property are ignored.
270
271#### `url.href`
272
273* {string}
274
275Gets and sets the serialized URL.
276
277```js
278const myURL = new URL('https://example.org/foo');
279console.log(myURL.href);
280// Prints https://example.org/foo
281
282myURL.href = 'https://example.com/bar';
283console.log(myURL.href);
284// Prints https://example.com/bar
285```
286
287Getting the value of the `href` property is equivalent to calling
288[`url.toString()`][].
289
290Setting the value of this property to a new value is equivalent to creating a
291new `URL` object using [`new URL(value)`][`new URL()`]. Each of the `URL`
292object's properties will be modified.
293
294If the value assigned to the `href` property is not a valid URL, a `TypeError`
295will be thrown.
296
297#### `url.origin`
298
299<!-- YAML
300changes:
301  - version: v15.0.0
302    pr-url: https://github.com/nodejs/node/pull/33325
303    description: The scheme "gopher" is no longer special and `url.origin` now
304                 returns `'null'` for it.
305-->
306
307* {string}
308
309Gets the read-only serialization of the URL's origin.
310
311```js
312const myURL = new URL('https://example.org/foo/bar?baz');
313console.log(myURL.origin);
314// Prints https://example.org
315```
316
317```js
318const idnURL = new URL('https://測試');
319console.log(idnURL.origin);
320// Prints https://xn--g6w251d
321
322console.log(idnURL.hostname);
323// Prints xn--g6w251d
324```
325
326#### `url.password`
327
328* {string}
329
330Gets and sets the password portion of the URL.
331
332```js
333const myURL = new URL('https://abc:xyz@example.com');
334console.log(myURL.password);
335// Prints xyz
336
337myURL.password = '123';
338console.log(myURL.href);
339// Prints https://abc:123@example.com/
340```
341
342Invalid URL characters included in the value assigned to the `password` property
343are [percent-encoded][]. The selection of which characters to
344percent-encode may vary somewhat from what the [`url.parse()`][] and
345[`url.format()`][] methods would produce.
346
347#### `url.pathname`
348
349* {string}
350
351Gets and sets the path portion of the URL.
352
353```js
354const myURL = new URL('https://example.org/abc/xyz?123');
355console.log(myURL.pathname);
356// Prints /abc/xyz
357
358myURL.pathname = '/abcdef';
359console.log(myURL.href);
360// Prints https://example.org/abcdef?123
361```
362
363Invalid URL characters included in the value assigned to the `pathname`
364property are [percent-encoded][]. The selection of which characters
365to percent-encode may vary somewhat from what the [`url.parse()`][] and
366[`url.format()`][] methods would produce.
367
368#### `url.port`
369
370<!-- YAML
371changes:
372  - version: v15.0.0
373    pr-url: https://github.com/nodejs/node/pull/33325
374    description: The scheme "gopher" is no longer special.
375-->
376
377* {string}
378
379Gets and sets the port portion of the URL.
380
381The port value may be a number or a string containing a number in the range
382`0` to `65535` (inclusive). Setting the value to the default port of the
383`URL` objects given `protocol` will result in the `port` value becoming
384the empty string (`''`).
385
386The port value can be an empty string in which case the port depends on
387the protocol/scheme:
388
389| protocol | port |
390| -------- | ---- |
391| "ftp"    | 21   |
392| "file"   |      |
393| "http"   | 80   |
394| "https"  | 443  |
395| "ws"     | 80   |
396| "wss"    | 443  |
397
398Upon assigning a value to the port, the value will first be converted to a
399string using `.toString()`.
400
401If that string is invalid but it begins with a number, the leading number is
402assigned to `port`.
403If the number lies outside the range denoted above, it is ignored.
404
405```js
406const myURL = new URL('https://example.org:8888');
407console.log(myURL.port);
408// Prints 8888
409
410// Default ports are automatically transformed to the empty string
411// (HTTPS protocol's default port is 443)
412myURL.port = '443';
413console.log(myURL.port);
414// Prints the empty string
415console.log(myURL.href);
416// Prints https://example.org/
417
418myURL.port = 1234;
419console.log(myURL.port);
420// Prints 1234
421console.log(myURL.href);
422// Prints https://example.org:1234/
423
424// Completely invalid port strings are ignored
425myURL.port = 'abcd';
426console.log(myURL.port);
427// Prints 1234
428
429// Leading numbers are treated as a port number
430myURL.port = '5678abcd';
431console.log(myURL.port);
432// Prints 5678
433
434// Non-integers are truncated
435myURL.port = 1234.5678;
436console.log(myURL.port);
437// Prints 1234
438
439// Out-of-range numbers which are not represented in scientific notation
440// will be ignored.
441myURL.port = 1e10; // 10000000000, will be range-checked as described below
442console.log(myURL.port);
443// Prints 1234
444```
445
446Numbers which contain a decimal point,
447such as floating-point numbers or numbers in scientific notation,
448are not an exception to this rule.
449Leading numbers up to the decimal point will be set as the URL's port,
450assuming they are valid:
451
452```js
453myURL.port = 4.567e21;
454console.log(myURL.port);
455// Prints 4 (because it is the leading number in the string '4.567e21')
456```
457
458#### `url.protocol`
459
460* {string}
461
462Gets and sets the protocol portion of the URL.
463
464```js
465const myURL = new URL('https://example.org');
466console.log(myURL.protocol);
467// Prints https:
468
469myURL.protocol = 'ftp';
470console.log(myURL.href);
471// Prints ftp://example.org/
472```
473
474Invalid URL protocol values assigned to the `protocol` property are ignored.
475
476##### Special schemes
477
478<!-- YAML
479changes:
480  - version: v15.0.0
481    pr-url: https://github.com/nodejs/node/pull/33325
482    description: The scheme "gopher" is no longer special.
483-->
484
485The [WHATWG URL Standard][] considers a handful of URL protocol schemes to be
486_special_ in terms of how they are parsed and serialized. When a URL is
487parsed using one of these special protocols, the `url.protocol` property
488may be changed to another special protocol but cannot be changed to a
489non-special protocol, and vice versa.
490
491For instance, changing from `http` to `https` works:
492
493```js
494const u = new URL('http://example.org');
495u.protocol = 'https';
496console.log(u.href);
497// https://example.org/
498```
499
500However, changing from `http` to a hypothetical `fish` protocol does not
501because the new protocol is not special.
502
503```js
504const u = new URL('http://example.org');
505u.protocol = 'fish';
506console.log(u.href);
507// http://example.org/
508```
509
510Likewise, changing from a non-special protocol to a special protocol is also
511not permitted:
512
513```js
514const u = new URL('fish://example.org');
515u.protocol = 'http';
516console.log(u.href);
517// fish://example.org
518```
519
520According to the WHATWG URL Standard, special protocol schemes are `ftp`,
521`file`, `http`, `https`, `ws`, and `wss`.
522
523#### `url.search`
524
525* {string}
526
527Gets and sets the serialized query portion of the URL.
528
529```js
530const myURL = new URL('https://example.org/abc?123');
531console.log(myURL.search);
532// Prints ?123
533
534myURL.search = 'abc=xyz';
535console.log(myURL.href);
536// Prints https://example.org/abc?abc=xyz
537```
538
539Any invalid URL characters appearing in the value assigned the `search`
540property will be [percent-encoded][]. The selection of which
541characters to percent-encode may vary somewhat from what the [`url.parse()`][]
542and [`url.format()`][] methods would produce.
543
544#### `url.searchParams`
545
546* {URLSearchParams}
547
548Gets the [`URLSearchParams`][] object representing the query parameters of the
549URL. This property is read-only but the `URLSearchParams` object it provides
550can be used to mutate the URL instance; to replace the entirety of query
551parameters of the URL, use the [`url.search`][] setter. See
552[`URLSearchParams`][] documentation for details.
553
554Use care when using `.searchParams` to modify the `URL` because,
555per the WHATWG specification, the `URLSearchParams` object uses
556different rules to determine which characters to percent-encode. For
557instance, the `URL` object will not percent encode the ASCII tilde (`~`)
558character, while `URLSearchParams` will always encode it:
559
560```js
561const myURL = new URL('https://example.org/abc?foo=~bar');
562
563console.log(myURL.search);  // prints ?foo=~bar
564
565// Modify the URL via searchParams...
566myURL.searchParams.sort();
567
568console.log(myURL.search);  // prints ?foo=%7Ebar
569```
570
571#### `url.username`
572
573* {string}
574
575Gets and sets the username portion of the URL.
576
577```js
578const myURL = new URL('https://abc:xyz@example.com');
579console.log(myURL.username);
580// Prints abc
581
582myURL.username = '123';
583console.log(myURL.href);
584// Prints https://123:xyz@example.com/
585```
586
587Any invalid URL characters appearing in the value assigned the `username`
588property will be [percent-encoded][]. The selection of which
589characters to percent-encode may vary somewhat from what the [`url.parse()`][]
590and [`url.format()`][] methods would produce.
591
592#### `url.toString()`
593
594* Returns: {string}
595
596The `toString()` method on the `URL` object returns the serialized URL. The
597value returned is equivalent to that of [`url.href`][] and [`url.toJSON()`][].
598
599#### `url.toJSON()`
600
601* Returns: {string}
602
603The `toJSON()` method on the `URL` object returns the serialized URL. The
604value returned is equivalent to that of [`url.href`][] and
605[`url.toString()`][].
606
607This method is automatically called when an `URL` object is serialized
608with [`JSON.stringify()`][].
609
610```js
611const myURLs = [
612  new URL('https://www.example.com'),
613  new URL('https://test.example.org'),
614];
615console.log(JSON.stringify(myURLs));
616// Prints ["https://www.example.com/","https://test.example.org/"]
617```
618
619#### `URL.createObjectURL(blob)`
620
621<!-- YAML
622added: v16.7.0
623-->
624
625> Stability: 1 - Experimental
626
627* `blob` {Blob}
628* Returns: {string}
629
630Creates a `'blob:nodedata:...'` URL string that represents the given {Blob}
631object and can be used to retrieve the `Blob` later.
632
633```js
634const {
635  Blob,
636  resolveObjectURL,
637} = require('node:buffer');
638
639const blob = new Blob(['hello']);
640const id = URL.createObjectURL(blob);
641
642// later...
643
644const otherBlob = resolveObjectURL(id);
645console.log(otherBlob.size);
646```
647
648The data stored by the registered {Blob} will be retained in memory until
649`URL.revokeObjectURL()` is called to remove it.
650
651`Blob` objects are registered within the current thread. If using Worker
652Threads, `Blob` objects registered within one Worker will not be available
653to other workers or the main thread.
654
655#### `URL.revokeObjectURL(id)`
656
657<!-- YAML
658added: v16.7.0
659-->
660
661> Stability: 1 - Experimental
662
663* `id` {string} A `'blob:nodedata:...` URL string returned by a prior call to
664  `URL.createObjectURL()`.
665
666Removes the stored {Blob} identified by the given ID. Attempting to revoke a
667ID that isn't registered will silently fail.
668
669#### `URL.canParse(input[, base])`
670
671<!-- YAML
672added: v18.17.0
673-->
674
675* `input` {string} The absolute or relative input URL to parse. If `input`
676  is relative, then `base` is required. If `input` is absolute, the `base`
677  is ignored. If `input` is not a string, it is [converted to a string][] first.
678* `base` {string} The base URL to resolve against if the `input` is not
679  absolute. If `base` is not a string, it is [converted to a string][] first.
680* Returns: {boolean}
681
682Checks if an `input` relative to the `base` can be parsed to a `URL`.
683
684```js
685const isValid = URL.canParse('/foo', 'https://example.org/'); // true
686
687const isNotValid = URL.canParse('/foo'); // false
688```
689
690### Class: `URLSearchParams`
691
692<!-- YAML
693added:
694  - v7.5.0
695  - v6.13.0
696changes:
697  - version: v10.0.0
698    pr-url: https://github.com/nodejs/node/pull/18281
699    description: The class is now available on the global object.
700-->
701
702The `URLSearchParams` API provides read and write access to the query of a
703`URL`. The `URLSearchParams` class can also be used standalone with one of the
704four following constructors.
705The `URLSearchParams` class is also available on the global object.
706
707The WHATWG `URLSearchParams` interface and the [`querystring`][] module have
708similar purpose, but the purpose of the [`querystring`][] module is more
709general, as it allows the customization of delimiter characters (`&` and `=`).
710On the other hand, this API is designed purely for URL query strings.
711
712```js
713const myURL = new URL('https://example.org/?abc=123');
714console.log(myURL.searchParams.get('abc'));
715// Prints 123
716
717myURL.searchParams.append('abc', 'xyz');
718console.log(myURL.href);
719// Prints https://example.org/?abc=123&abc=xyz
720
721myURL.searchParams.delete('abc');
722myURL.searchParams.set('a', 'b');
723console.log(myURL.href);
724// Prints https://example.org/?a=b
725
726const newSearchParams = new URLSearchParams(myURL.searchParams);
727// The above is equivalent to
728// const newSearchParams = new URLSearchParams(myURL.search);
729
730newSearchParams.append('a', 'c');
731console.log(myURL.href);
732// Prints https://example.org/?a=b
733console.log(newSearchParams.toString());
734// Prints a=b&a=c
735
736// newSearchParams.toString() is implicitly called
737myURL.search = newSearchParams;
738console.log(myURL.href);
739// Prints https://example.org/?a=b&a=c
740newSearchParams.delete('a');
741console.log(myURL.href);
742// Prints https://example.org/?a=b&a=c
743```
744
745#### `new URLSearchParams()`
746
747Instantiate a new empty `URLSearchParams` object.
748
749#### `new URLSearchParams(string)`
750
751* `string` {string} A query string
752
753Parse the `string` as a query string, and use it to instantiate a new
754`URLSearchParams` object. A leading `'?'`, if present, is ignored.
755
756```js
757let params;
758
759params = new URLSearchParams('user=abc&query=xyz');
760console.log(params.get('user'));
761// Prints 'abc'
762console.log(params.toString());
763// Prints 'user=abc&query=xyz'
764
765params = new URLSearchParams('?user=abc&query=xyz');
766console.log(params.toString());
767// Prints 'user=abc&query=xyz'
768```
769
770#### `new URLSearchParams(obj)`
771
772<!-- YAML
773added:
774  - v7.10.0
775  - v6.13.0
776-->
777
778* `obj` {Object} An object representing a collection of key-value pairs
779
780Instantiate a new `URLSearchParams` object with a query hash map. The key and
781value of each property of `obj` are always coerced to strings.
782
783Unlike [`querystring`][] module, duplicate keys in the form of array values are
784not allowed. Arrays are stringified using [`array.toString()`][], which simply
785joins all array elements with commas.
786
787```js
788const params = new URLSearchParams({
789  user: 'abc',
790  query: ['first', 'second'],
791});
792console.log(params.getAll('query'));
793// Prints [ 'first,second' ]
794console.log(params.toString());
795// Prints 'user=abc&query=first%2Csecond'
796```
797
798#### `new URLSearchParams(iterable)`
799
800<!-- YAML
801added:
802  - v7.10.0
803  - v6.13.0
804-->
805
806* `iterable` {Iterable} An iterable object whose elements are key-value pairs
807
808Instantiate a new `URLSearchParams` object with an iterable map in a way that
809is similar to [`Map`][]'s constructor. `iterable` can be an `Array` or any
810iterable object. That means `iterable` can be another `URLSearchParams`, in
811which case the constructor will simply create a clone of the provided
812`URLSearchParams`. Elements of `iterable` are key-value pairs, and can
813themselves be any iterable object.
814
815Duplicate keys are allowed.
816
817```js
818let params;
819
820// Using an array
821params = new URLSearchParams([
822  ['user', 'abc'],
823  ['query', 'first'],
824  ['query', 'second'],
825]);
826console.log(params.toString());
827// Prints 'user=abc&query=first&query=second'
828
829// Using a Map object
830const map = new Map();
831map.set('user', 'abc');
832map.set('query', 'xyz');
833params = new URLSearchParams(map);
834console.log(params.toString());
835// Prints 'user=abc&query=xyz'
836
837// Using a generator function
838function* getQueryPairs() {
839  yield ['user', 'abc'];
840  yield ['query', 'first'];
841  yield ['query', 'second'];
842}
843params = new URLSearchParams(getQueryPairs());
844console.log(params.toString());
845// Prints 'user=abc&query=first&query=second'
846
847// Each key-value pair must have exactly two elements
848new URLSearchParams([
849  ['user', 'abc', 'error'],
850]);
851// Throws TypeError [ERR_INVALID_TUPLE]:
852//        Each query pair must be an iterable [name, value] tuple
853```
854
855#### `urlSearchParams.append(name, value)`
856
857* `name` {string}
858* `value` {string}
859
860Append a new name-value pair to the query string.
861
862#### `urlSearchParams.delete(name[, value])`
863
864<!-- YAML
865changes:
866  - version: v18.18.0
867    pr-url: https://github.com/nodejs/node/pull/47885
868    description: Add support for optional `value` argument.
869-->
870
871* `name` {string}
872* `value` {string}
873
874If `value` is provided, removes all name-value pairs
875where name is `name` and value is `value`..
876
877If `value` is not provided, removes all name-value pairs whose name is `name`.
878
879#### `urlSearchParams.entries()`
880
881* Returns: {Iterator}
882
883Returns an ES6 `Iterator` over each of the name-value pairs in the query.
884Each item of the iterator is a JavaScript `Array`. The first item of the `Array`
885is the `name`, the second item of the `Array` is the `value`.
886
887Alias for [`urlSearchParams[@@iterator]()`][`urlSearchParams@@iterator()`].
888
889#### `urlSearchParams.forEach(fn[, thisArg])`
890
891<!-- YAML
892changes:
893  - version: v18.0.0
894    pr-url: https://github.com/nodejs/node/pull/41678
895    description: Passing an invalid callback to the `fn` argument
896                 now throws `ERR_INVALID_ARG_TYPE` instead of
897                 `ERR_INVALID_CALLBACK`.
898-->
899
900* `fn` {Function} Invoked for each name-value pair in the query
901* `thisArg` {Object} To be used as `this` value for when `fn` is called
902
903Iterates over each name-value pair in the query and invokes the given function.
904
905```js
906const myURL = new URL('https://example.org/?a=b&c=d');
907myURL.searchParams.forEach((value, name, searchParams) => {
908  console.log(name, value, myURL.searchParams === searchParams);
909});
910// Prints:
911//   a b true
912//   c d true
913```
914
915#### `urlSearchParams.get(name)`
916
917* `name` {string}
918* Returns: {string} or `null` if there is no name-value pair with the given
919  `name`.
920
921Returns the value of the first name-value pair whose name is `name`. If there
922are no such pairs, `null` is returned.
923
924#### `urlSearchParams.getAll(name)`
925
926* `name` {string}
927* Returns: {string\[]}
928
929Returns the values of all name-value pairs whose name is `name`. If there are
930no such pairs, an empty array is returned.
931
932#### `urlSearchParams.has(name[, value])`
933
934<!-- YAML
935changes:
936  - version: v18.18.0
937    pr-url: https://github.com/nodejs/node/pull/47885
938    description: Add support for optional `value` argument.
939-->
940
941* `name` {string}
942* `value` {string}
943* Returns: {boolean}
944
945Checks if the `URLSearchParams` object contains key-value pair(s) based on
946`name` and an optional `value` argument.
947
948If `value` is provided, returns `true` when name-value pair with
949same `name` and `value` exists.
950
951If `value` is not provided, returns `true` if there is at least one name-value
952pair whose name is `name`.
953
954#### `urlSearchParams.keys()`
955
956* Returns: {Iterator}
957
958Returns an ES6 `Iterator` over the names of each name-value pair.
959
960```js
961const params = new URLSearchParams('foo=bar&foo=baz');
962for (const name of params.keys()) {
963  console.log(name);
964}
965// Prints:
966//   foo
967//   foo
968```
969
970#### `urlSearchParams.set(name, value)`
971
972* `name` {string}
973* `value` {string}
974
975Sets the value in the `URLSearchParams` object associated with `name` to
976`value`. If there are any pre-existing name-value pairs whose names are `name`,
977set the first such pair's value to `value` and remove all others. If not,
978append the name-value pair to the query string.
979
980```js
981const params = new URLSearchParams();
982params.append('foo', 'bar');
983params.append('foo', 'baz');
984params.append('abc', 'def');
985console.log(params.toString());
986// Prints foo=bar&foo=baz&abc=def
987
988params.set('foo', 'def');
989params.set('xyz', 'opq');
990console.log(params.toString());
991// Prints foo=def&abc=def&xyz=opq
992```
993
994#### `urlSearchParams.size`
995
996<!-- YAML
997added: v18.16.0
998-->
999
1000The total number of parameter entries.
1001
1002#### `urlSearchParams.sort()`
1003
1004<!-- YAML
1005added:
1006  - v7.7.0
1007  - v6.13.0
1008-->
1009
1010Sort all existing name-value pairs in-place by their names. Sorting is done
1011with a [stable sorting algorithm][], so relative order between name-value pairs
1012with the same name is preserved.
1013
1014This method can be used, in particular, to increase cache hits.
1015
1016```js
1017const params = new URLSearchParams('query[]=abc&type=search&query[]=123');
1018params.sort();
1019console.log(params.toString());
1020// Prints query%5B%5D=abc&query%5B%5D=123&type=search
1021```
1022
1023#### `urlSearchParams.toString()`
1024
1025* Returns: {string}
1026
1027Returns the search parameters serialized as a string, with characters
1028percent-encoded where necessary.
1029
1030#### `urlSearchParams.values()`
1031
1032* Returns: {Iterator}
1033
1034Returns an ES6 `Iterator` over the values of each name-value pair.
1035
1036#### `urlSearchParams[Symbol.iterator]()`
1037
1038* Returns: {Iterator}
1039
1040Returns an ES6 `Iterator` over each of the name-value pairs in the query string.
1041Each item of the iterator is a JavaScript `Array`. The first item of the `Array`
1042is the `name`, the second item of the `Array` is the `value`.
1043
1044Alias for [`urlSearchParams.entries()`][].
1045
1046```js
1047const params = new URLSearchParams('foo=bar&xyz=baz');
1048for (const [name, value] of params) {
1049  console.log(name, value);
1050}
1051// Prints:
1052//   foo bar
1053//   xyz baz
1054```
1055
1056### `url.domainToASCII(domain)`
1057
1058<!-- YAML
1059added:
1060  - v7.4.0
1061  - v6.13.0
1062changes:
1063  - version: v18.17.0
1064    pr-url: https://github.com/nodejs/node/pull/47339
1065    description: ICU requirement is removed.
1066-->
1067
1068* `domain` {string}
1069* Returns: {string}
1070
1071Returns the [Punycode][] ASCII serialization of the `domain`. If `domain` is an
1072invalid domain, the empty string is returned.
1073
1074It performs the inverse operation to [`url.domainToUnicode()`][].
1075
1076```mjs
1077import url from 'node:url';
1078
1079console.log(url.domainToASCII('español.com'));
1080// Prints xn--espaol-zwa.com
1081console.log(url.domainToASCII('中文.com'));
1082// Prints xn--fiq228c.com
1083console.log(url.domainToASCII('xn--iñvalid.com'));
1084// Prints an empty string
1085```
1086
1087```cjs
1088const url = require('node:url');
1089
1090console.log(url.domainToASCII('español.com'));
1091// Prints xn--espaol-zwa.com
1092console.log(url.domainToASCII('中文.com'));
1093// Prints xn--fiq228c.com
1094console.log(url.domainToASCII('xn--iñvalid.com'));
1095// Prints an empty string
1096```
1097
1098### `url.domainToUnicode(domain)`
1099
1100<!-- YAML
1101added:
1102  - v7.4.0
1103  - v6.13.0
1104changes:
1105  - version: v18.17.0
1106    pr-url: https://github.com/nodejs/node/pull/47339
1107    description: ICU requirement is removed.
1108-->
1109
1110* `domain` {string}
1111* Returns: {string}
1112
1113Returns the Unicode serialization of the `domain`. If `domain` is an invalid
1114domain, the empty string is returned.
1115
1116It performs the inverse operation to [`url.domainToASCII()`][].
1117
1118```mjs
1119import url from 'node:url';
1120
1121console.log(url.domainToUnicode('xn--espaol-zwa.com'));
1122// Prints español.com
1123console.log(url.domainToUnicode('xn--fiq228c.com'));
1124// Prints 中文.com
1125console.log(url.domainToUnicode('xn--iñvalid.com'));
1126// Prints an empty string
1127```
1128
1129```cjs
1130const url = require('node:url');
1131
1132console.log(url.domainToUnicode('xn--espaol-zwa.com'));
1133// Prints español.com
1134console.log(url.domainToUnicode('xn--fiq228c.com'));
1135// Prints 中文.com
1136console.log(url.domainToUnicode('xn--iñvalid.com'));
1137// Prints an empty string
1138```
1139
1140### `url.fileURLToPath(url)`
1141
1142<!-- YAML
1143added: v10.12.0
1144-->
1145
1146* `url` {URL | string} The file URL string or URL object to convert to a path.
1147* Returns: {string} The fully-resolved platform-specific Node.js file path.
1148
1149This function ensures the correct decodings of percent-encoded characters as
1150well as ensuring a cross-platform valid absolute path string.
1151
1152```mjs
1153import { fileURLToPath } from 'node:url';
1154
1155const __filename = fileURLToPath(import.meta.url);
1156
1157new URL('file:///C:/path/').pathname;      // Incorrect: /C:/path/
1158fileURLToPath('file:///C:/path/');         // Correct:   C:\path\ (Windows)
1159
1160new URL('file://nas/foo.txt').pathname;    // Incorrect: /foo.txt
1161fileURLToPath('file://nas/foo.txt');       // Correct:   \\nas\foo.txt (Windows)
1162
1163new URL('file:///你好.txt').pathname;      // Incorrect: /%E4%BD%A0%E5%A5%BD.txt
1164fileURLToPath('file:///你好.txt');         // Correct:   /你好.txt (POSIX)
1165
1166new URL('file:///hello world').pathname;   // Incorrect: /hello%20world
1167fileURLToPath('file:///hello world');      // Correct:   /hello world (POSIX)
1168```
1169
1170```cjs
1171const { fileURLToPath } = require('node:url');
1172new URL('file:///C:/path/').pathname;      // Incorrect: /C:/path/
1173fileURLToPath('file:///C:/path/');         // Correct:   C:\path\ (Windows)
1174
1175new URL('file://nas/foo.txt').pathname;    // Incorrect: /foo.txt
1176fileURLToPath('file://nas/foo.txt');       // Correct:   \\nas\foo.txt (Windows)
1177
1178new URL('file:///你好.txt').pathname;      // Incorrect: /%E4%BD%A0%E5%A5%BD.txt
1179fileURLToPath('file:///你好.txt');         // Correct:   /你好.txt (POSIX)
1180
1181new URL('file:///hello world').pathname;   // Incorrect: /hello%20world
1182fileURLToPath('file:///hello world');      // Correct:   /hello world (POSIX)
1183```
1184
1185### `url.format(URL[, options])`
1186
1187<!-- YAML
1188added: v7.6.0
1189-->
1190
1191* `URL` {URL} A [WHATWG URL][] object
1192* `options` {Object}
1193  * `auth` {boolean} `true` if the serialized URL string should include the
1194    username and password, `false` otherwise. **Default:** `true`.
1195  * `fragment` {boolean} `true` if the serialized URL string should include the
1196    fragment, `false` otherwise. **Default:** `true`.
1197  * `search` {boolean} `true` if the serialized URL string should include the
1198    search query, `false` otherwise. **Default:** `true`.
1199  * `unicode` {boolean} `true` if Unicode characters appearing in the host
1200    component of the URL string should be encoded directly as opposed to being
1201    Punycode encoded. **Default:** `false`.
1202* Returns: {string}
1203
1204Returns a customizable serialization of a URL `String` representation of a
1205[WHATWG URL][] object.
1206
1207The URL object has both a `toString()` method and `href` property that return
1208string serializations of the URL. These are not, however, customizable in
1209any way. The `url.format(URL[, options])` method allows for basic customization
1210of the output.
1211
1212```mjs
1213import url from 'node:url';
1214const myURL = new URL('https://a:b@測試?abc#foo');
1215
1216console.log(myURL.href);
1217// Prints https://a:b@xn--g6w251d/?abc#foo
1218
1219console.log(myURL.toString());
1220// Prints https://a:b@xn--g6w251d/?abc#foo
1221
1222console.log(url.format(myURL, { fragment: false, unicode: true, auth: false }));
1223// Prints 'https://測試/?abc'
1224```
1225
1226```cjs
1227const url = require('node:url');
1228const myURL = new URL('https://a:b@測試?abc#foo');
1229
1230console.log(myURL.href);
1231// Prints https://a:b@xn--g6w251d/?abc#foo
1232
1233console.log(myURL.toString());
1234// Prints https://a:b@xn--g6w251d/?abc#foo
1235
1236console.log(url.format(myURL, { fragment: false, unicode: true, auth: false }));
1237// Prints 'https://測試/?abc'
1238```
1239
1240### `url.pathToFileURL(path)`
1241
1242<!-- YAML
1243added: v10.12.0
1244-->
1245
1246* `path` {string} The path to convert to a File URL.
1247* Returns: {URL} The file URL object.
1248
1249This function ensures that `path` is resolved absolutely, and that the URL
1250control characters are correctly encoded when converting into a File URL.
1251
1252```mjs
1253import { pathToFileURL } from 'node:url';
1254
1255new URL('/foo#1', 'file:');           // Incorrect: file:///foo#1
1256pathToFileURL('/foo#1');              // Correct:   file:///foo%231 (POSIX)
1257
1258new URL('/some/path%.c', 'file:');    // Incorrect: file:///some/path%.c
1259pathToFileURL('/some/path%.c');       // Correct:   file:///some/path%25.c (POSIX)
1260```
1261
1262```cjs
1263const { pathToFileURL } = require('node:url');
1264new URL(__filename);                  // Incorrect: throws (POSIX)
1265new URL(__filename);                  // Incorrect: C:\... (Windows)
1266pathToFileURL(__filename);            // Correct:   file:///... (POSIX)
1267pathToFileURL(__filename);            // Correct:   file:///C:/... (Windows)
1268
1269new URL('/foo#1', 'file:');           // Incorrect: file:///foo#1
1270pathToFileURL('/foo#1');              // Correct:   file:///foo%231 (POSIX)
1271
1272new URL('/some/path%.c', 'file:');    // Incorrect: file:///some/path%.c
1273pathToFileURL('/some/path%.c');       // Correct:   file:///some/path%25.c (POSIX)
1274```
1275
1276### `url.urlToHttpOptions(url)`
1277
1278<!-- YAML
1279added:
1280  - v15.7.0
1281  - v14.18.0
1282changes:
1283  - version: v18.17.0
1284    pr-url: https://github.com/nodejs/node/pull/46989
1285    description: The returned object will also contain all the own enumerable
1286                 properties of the `url` argument.
1287-->
1288
1289* `url` {URL} The [WHATWG URL][] object to convert to an options object.
1290* Returns: {Object} Options object
1291  * `protocol` {string} Protocol to use.
1292  * `hostname` {string} A domain name or IP address of the server to issue the
1293    request to.
1294  * `hash` {string} The fragment portion of the URL.
1295  * `search` {string} The serialized query portion of the URL.
1296  * `pathname` {string} The path portion of the URL.
1297  * `path` {string} Request path. Should include query string if any.
1298    E.G. `'/index.html?page=12'`. An exception is thrown when the request path
1299    contains illegal characters. Currently, only spaces are rejected but that
1300    may change in the future.
1301  * `href` {string} The serialized URL.
1302  * `port` {number} Port of remote server.
1303  * `auth` {string} Basic authentication i.e. `'user:password'` to compute an
1304    Authorization header.
1305
1306This utility function converts a URL object into an ordinary options object as
1307expected by the [`http.request()`][] and [`https.request()`][] APIs.
1308
1309```mjs
1310import { urlToHttpOptions } from 'node:url';
1311const myURL = new URL('https://a:b@測試?abc#foo');
1312
1313console.log(urlToHttpOptions(myURL));
1314/*
1315{
1316  protocol: 'https:',
1317  hostname: 'xn--g6w251d',
1318  hash: '#foo',
1319  search: '?abc',
1320  pathname: '/',
1321  path: '/?abc',
1322  href: 'https://a:b@xn--g6w251d/?abc#foo',
1323  auth: 'a:b'
1324}
1325*/
1326```
1327
1328```cjs
1329const { urlToHttpOptions } = require('node:url');
1330const myURL = new URL('https://a:b@測試?abc#foo');
1331
1332console.log(urlToHttpOptions(myURL));
1333/*
1334{
1335  protocol: 'https:',
1336  hostname: 'xn--g6w251d',
1337  hash: '#foo',
1338  search: '?abc',
1339  pathname: '/',
1340  path: '/?abc',
1341  href: 'https://a:b@xn--g6w251d/?abc#foo',
1342  auth: 'a:b'
1343}
1344*/
1345```
1346
1347## Legacy URL API
1348
1349<!-- YAML
1350changes:
1351  - version:
1352      - v15.13.0
1353      - v14.17.0
1354    pr-url: https://github.com/nodejs/node/pull/37784
1355    description: Deprecation revoked. Status changed to "Legacy".
1356  - version: v11.0.0
1357    pr-url: https://github.com/nodejs/node/pull/22715
1358    description: This API is deprecated.
1359-->
1360
1361> Stability: 3 - Legacy: Use the WHATWG URL API instead.
1362
1363### Legacy `urlObject`
1364
1365<!-- YAML
1366changes:
1367  - version:
1368      - v15.13.0
1369      - v14.17.0
1370    pr-url: https://github.com/nodejs/node/pull/37784
1371    description: Deprecation revoked. Status changed to "Legacy".
1372  - version: v11.0.0
1373    pr-url: https://github.com/nodejs/node/pull/22715
1374    description: The Legacy URL API is deprecated. Use the WHATWG URL API.
1375-->
1376
1377> Stability: 3 - Legacy: Use the WHATWG URL API instead.
1378
1379The legacy `urlObject` (`require('node:url').Url` or
1380`import { Url } from 'node:url'`) is
1381created and returned by the `url.parse()` function.
1382
1383#### `urlObject.auth`
1384
1385The `auth` property is the username and password portion of the URL, also
1386referred to as _userinfo_. This string subset follows the `protocol` and
1387double slashes (if present) and precedes the `host` component, delimited by `@`.
1388The string is either the username, or it is the username and password separated
1389by `:`.
1390
1391For example: `'user:pass'`.
1392
1393#### `urlObject.hash`
1394
1395The `hash` property is the fragment identifier portion of the URL including the
1396leading `#` character.
1397
1398For example: `'#hash'`.
1399
1400#### `urlObject.host`
1401
1402The `host` property is the full lower-cased host portion of the URL, including
1403the `port` if specified.
1404
1405For example: `'sub.example.com:8080'`.
1406
1407#### `urlObject.hostname`
1408
1409The `hostname` property is the lower-cased host name portion of the `host`
1410component _without_ the `port` included.
1411
1412For example: `'sub.example.com'`.
1413
1414#### `urlObject.href`
1415
1416The `href` property is the full URL string that was parsed with both the
1417`protocol` and `host` components converted to lower-case.
1418
1419For example: `'http://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash'`.
1420
1421#### `urlObject.path`
1422
1423The `path` property is a concatenation of the `pathname` and `search`
1424components.
1425
1426For example: `'/p/a/t/h?query=string'`.
1427
1428No decoding of the `path` is performed.
1429
1430#### `urlObject.pathname`
1431
1432The `pathname` property consists of the entire path section of the URL. This
1433is everything following the `host` (including the `port`) and before the start
1434of the `query` or `hash` components, delimited by either the ASCII question
1435mark (`?`) or hash (`#`) characters.
1436
1437For example: `'/p/a/t/h'`.
1438
1439No decoding of the path string is performed.
1440
1441#### `urlObject.port`
1442
1443The `port` property is the numeric port portion of the `host` component.
1444
1445For example: `'8080'`.
1446
1447#### `urlObject.protocol`
1448
1449The `protocol` property identifies the URL's lower-cased protocol scheme.
1450
1451For example: `'http:'`.
1452
1453#### `urlObject.query`
1454
1455The `query` property is either the query string without the leading ASCII
1456question mark (`?`), or an object returned by the [`querystring`][] module's
1457`parse()` method. Whether the `query` property is a string or object is
1458determined by the `parseQueryString` argument passed to `url.parse()`.
1459
1460For example: `'query=string'` or `{'query': 'string'}`.
1461
1462If returned as a string, no decoding of the query string is performed. If
1463returned as an object, both keys and values are decoded.
1464
1465#### `urlObject.search`
1466
1467The `search` property consists of the entire "query string" portion of the
1468URL, including the leading ASCII question mark (`?`) character.
1469
1470For example: `'?query=string'`.
1471
1472No decoding of the query string is performed.
1473
1474#### `urlObject.slashes`
1475
1476The `slashes` property is a `boolean` with a value of `true` if two ASCII
1477forward-slash characters (`/`) are required following the colon in the
1478`protocol`.
1479
1480### `url.format(urlObject)`
1481
1482<!-- YAML
1483added: v0.1.25
1484changes:
1485  - version: v17.0.0
1486    pr-url: https://github.com/nodejs/node/pull/38631
1487    description: Now throws an `ERR_INVALID_URL` exception when Punycode
1488                 conversion of a hostname introduces changes that could cause
1489                 the URL to be re-parsed differently.
1490  - version:
1491      - v15.13.0
1492      - v14.17.0
1493    pr-url: https://github.com/nodejs/node/pull/37784
1494    description: Deprecation revoked. Status changed to "Legacy".
1495  - version: v11.0.0
1496    pr-url: https://github.com/nodejs/node/pull/22715
1497    description: The Legacy URL API is deprecated. Use the WHATWG URL API.
1498  - version: v7.0.0
1499    pr-url: https://github.com/nodejs/node/pull/7234
1500    description: URLs with a `file:` scheme will now always use the correct
1501                 number of slashes regardless of `slashes` option. A falsy
1502                 `slashes` option with no protocol is now also respected at all
1503                 times.
1504-->
1505
1506> Stability: 3 - Legacy: Use the WHATWG URL API instead.
1507
1508* `urlObject` {Object|string} A URL object (as returned by `url.parse()` or
1509  constructed otherwise). If a string, it is converted to an object by passing
1510  it to `url.parse()`.
1511
1512The `url.format()` method returns a formatted URL string derived from
1513`urlObject`.
1514
1515```js
1516const url = require('node:url');
1517url.format({
1518  protocol: 'https',
1519  hostname: 'example.com',
1520  pathname: '/some/path',
1521  query: {
1522    page: 1,
1523    format: 'json',
1524  },
1525});
1526
1527// => 'https://example.com/some/path?page=1&format=json'
1528```
1529
1530If `urlObject` is not an object or a string, `url.format()` will throw a
1531[`TypeError`][].
1532
1533The formatting process operates as follows:
1534
1535* A new empty string `result` is created.
1536* If `urlObject.protocol` is a string, it is appended as-is to `result`.
1537* Otherwise, if `urlObject.protocol` is not `undefined` and is not a string, an
1538  [`Error`][] is thrown.
1539* For all string values of `urlObject.protocol` that _do not end_ with an ASCII
1540  colon (`:`) character, the literal string `:` will be appended to `result`.
1541* If either of the following conditions is true, then the literal string `//`
1542  will be appended to `result`:
1543  * `urlObject.slashes` property is true;
1544  * `urlObject.protocol` begins with `http`, `https`, `ftp`, `gopher`, or
1545    `file`;
1546* If the value of the `urlObject.auth` property is truthy, and either
1547  `urlObject.host` or `urlObject.hostname` are not `undefined`, the value of
1548  `urlObject.auth` will be coerced into a string and appended to `result`
1549  followed by the literal string `@`.
1550* If the `urlObject.host` property is `undefined` then:
1551  * If the `urlObject.hostname` is a string, it is appended to `result`.
1552  * Otherwise, if `urlObject.hostname` is not `undefined` and is not a string,
1553    an [`Error`][] is thrown.
1554  * If the `urlObject.port` property value is truthy, and `urlObject.hostname`
1555    is not `undefined`:
1556    * The literal string `:` is appended to `result`, and
1557    * The value of `urlObject.port` is coerced to a string and appended to
1558      `result`.
1559* Otherwise, if the `urlObject.host` property value is truthy, the value of
1560  `urlObject.host` is coerced to a string and appended to `result`.
1561* If the `urlObject.pathname` property is a string that is not an empty string:
1562  * If the `urlObject.pathname` _does not start_ with an ASCII forward slash
1563    (`/`), then the literal string `'/'` is appended to `result`.
1564  * The value of `urlObject.pathname` is appended to `result`.
1565* Otherwise, if `urlObject.pathname` is not `undefined` and is not a string, an
1566  [`Error`][] is thrown.
1567* If the `urlObject.search` property is `undefined` and if the `urlObject.query`
1568  property is an `Object`, the literal string `?` is appended to `result`
1569  followed by the output of calling the [`querystring`][] module's `stringify()`
1570  method passing the value of `urlObject.query`.
1571* Otherwise, if `urlObject.search` is a string:
1572  * If the value of `urlObject.search` _does not start_ with the ASCII question
1573    mark (`?`) character, the literal string `?` is appended to `result`.
1574  * The value of `urlObject.search` is appended to `result`.
1575* Otherwise, if `urlObject.search` is not `undefined` and is not a string, an
1576  [`Error`][] is thrown.
1577* If the `urlObject.hash` property is a string:
1578  * If the value of `urlObject.hash` _does not start_ with the ASCII hash (`#`)
1579    character, the literal string `#` is appended to `result`.
1580  * The value of `urlObject.hash` is appended to `result`.
1581* Otherwise, if the `urlObject.hash` property is not `undefined` and is not a
1582  string, an [`Error`][] is thrown.
1583* `result` is returned.
1584
1585### `url.parse(urlString[, parseQueryString[, slashesDenoteHost]])`
1586
1587<!-- YAML
1588added: v0.1.25
1589changes:
1590  - version: v18.13.0
1591    pr-url: https://github.com/nodejs/node/pull/44919
1592    description: Documentation-only deprecation.
1593  - version:
1594      - v15.13.0
1595      - v14.17.0
1596    pr-url: https://github.com/nodejs/node/pull/37784
1597    description: Deprecation revoked. Status changed to "Legacy".
1598  - version: v11.14.0
1599    pr-url: https://github.com/nodejs/node/pull/26941
1600    description: The `pathname` property on the returned URL object is now `/`
1601                 when there is no path and the protocol scheme is `ws:` or
1602                 `wss:`.
1603  - version: v11.0.0
1604    pr-url: https://github.com/nodejs/node/pull/22715
1605    description: The Legacy URL API is deprecated. Use the WHATWG URL API.
1606  - version: v9.0.0
1607    pr-url: https://github.com/nodejs/node/pull/13606
1608    description: The `search` property on the returned URL object is now `null`
1609                 when no query string is present.
1610-->
1611
1612> Stability: 0 - Deprecated: Use the WHATWG URL API instead.
1613
1614* `urlString` {string} The URL string to parse.
1615* `parseQueryString` {boolean} If `true`, the `query` property will always
1616  be set to an object returned by the [`querystring`][] module's `parse()`
1617  method. If `false`, the `query` property on the returned URL object will be an
1618  unparsed, undecoded string. **Default:** `false`.
1619* `slashesDenoteHost` {boolean} If `true`, the first token after the literal
1620  string `//` and preceding the next `/` will be interpreted as the `host`.
1621  For instance, given `//foo/bar`, the result would be
1622  `{host: 'foo', pathname: '/bar'}` rather than `{pathname: '//foo/bar'}`.
1623  **Default:** `false`.
1624
1625The `url.parse()` method takes a URL string, parses it, and returns a URL
1626object.
1627
1628A `TypeError` is thrown if `urlString` is not a string.
1629
1630A `URIError` is thrown if the `auth` property is present but cannot be decoded.
1631
1632`url.parse()` uses a lenient, non-standard algorithm for parsing URL
1633strings. It is prone to security issues such as [host name spoofing][]
1634and incorrect handling of usernames and passwords. Do not use with untrusted
1635input. CVEs are not issued for `url.parse()` vulnerabilities. Use the
1636[WHATWG URL][] API instead.
1637
1638### `url.resolve(from, to)`
1639
1640<!-- YAML
1641added: v0.1.25
1642changes:
1643  - version:
1644      - v15.13.0
1645      - v14.17.0
1646    pr-url: https://github.com/nodejs/node/pull/37784
1647    description: Deprecation revoked. Status changed to "Legacy".
1648  - version: v11.0.0
1649    pr-url: https://github.com/nodejs/node/pull/22715
1650    description: The Legacy URL API is deprecated. Use the WHATWG URL API.
1651  - version: v6.6.0
1652    pr-url: https://github.com/nodejs/node/pull/8215
1653    description: The `auth` fields are now kept intact when `from` and `to`
1654                 refer to the same host.
1655  - version:
1656    - v6.5.0
1657    - v4.6.2
1658    pr-url: https://github.com/nodejs/node/pull/8214
1659    description: The `port` field is copied correctly now.
1660  - version: v6.0.0
1661    pr-url: https://github.com/nodejs/node/pull/1480
1662    description: The `auth` fields is cleared now the `to` parameter
1663                 contains a hostname.
1664-->
1665
1666> Stability: 3 - Legacy: Use the WHATWG URL API instead.
1667
1668* `from` {string} The base URL to use if `to` is a relative URL.
1669* `to` {string} The target URL to resolve.
1670
1671The `url.resolve()` method resolves a target URL relative to a base URL in a
1672manner similar to that of a web browser resolving an anchor tag.
1673
1674```js
1675const url = require('node:url');
1676url.resolve('/one/two/three', 'four');         // '/one/two/four'
1677url.resolve('http://example.com/', '/one');    // 'http://example.com/one'
1678url.resolve('http://example.com/one', '/two'); // 'http://example.com/two'
1679```
1680
1681To achieve the same result using the WHATWG URL API:
1682
1683```js
1684function resolve(from, to) {
1685  const resolvedUrl = new URL(to, new URL(from, 'resolve://'));
1686  if (resolvedUrl.protocol === 'resolve:') {
1687    // `from` is a relative URL.
1688    const { pathname, search, hash } = resolvedUrl;
1689    return pathname + search + hash;
1690  }
1691  return resolvedUrl.toString();
1692}
1693
1694resolve('/one/two/three', 'four');         // '/one/two/four'
1695resolve('http://example.com/', '/one');    // 'http://example.com/one'
1696resolve('http://example.com/one', '/two'); // 'http://example.com/two'
1697```
1698
1699<a id="whatwg-percent-encoding"></a>
1700
1701## Percent-encoding in URLs
1702
1703URLs are permitted to only contain a certain range of characters. Any character
1704falling outside of that range must be encoded. How such characters are encoded,
1705and which characters to encode depends entirely on where the character is
1706located within the structure of the URL.
1707
1708### Legacy API
1709
1710Within the Legacy API, spaces (`' '`) and the following characters will be
1711automatically escaped in the properties of URL objects:
1712
1713```text
1714< > " ` \r \n \t { } | \ ^ '
1715```
1716
1717For example, the ASCII space character (`' '`) is encoded as `%20`. The ASCII
1718forward slash (`/`) character is encoded as `%3C`.
1719
1720### WHATWG API
1721
1722The [WHATWG URL Standard][] uses a more selective and fine grained approach to
1723selecting encoded characters than that used by the Legacy API.
1724
1725The WHATWG algorithm defines four "percent-encode sets" that describe ranges
1726of characters that must be percent-encoded:
1727
1728* The _C0 control percent-encode set_ includes code points in range U+0000 to
1729  U+001F (inclusive) and all code points greater than U+007E (\~).
1730
1731* The _fragment percent-encode set_ includes the _C0 control percent-encode set_
1732  and code points U+0020 SPACE, U+0022 ("), U+003C (<), U+003E (>),
1733  and U+0060 (\`).
1734
1735* The _path percent-encode set_ includes the _C0 control percent-encode set_
1736  and code points U+0020 SPACE, U+0022 ("), U+0023 (#), U+003C (<), U+003E (>),
1737  U+003F (?), U+0060 (\`), U+007B ({), and U+007D (}).
1738
1739* The _userinfo encode set_ includes the _path percent-encode set_ and code
1740  points U+002F (/), U+003A (:), U+003B (;), U+003D (=), U+0040 (@),
1741  U+005B (\[) to U+005E(^), and U+007C (|).
1742
1743The _userinfo percent-encode set_ is used exclusively for username and
1744passwords encoded within the URL. The _path percent-encode set_ is used for the
1745path of most URLs. The _fragment percent-encode set_ is used for URL fragments.
1746The _C0 control percent-encode set_ is used for host and path under certain
1747specific conditions, in addition to all other cases.
1748
1749When non-ASCII characters appear within a host name, the host name is encoded
1750using the [Punycode][] algorithm. Note, however, that a host name _may_ contain
1751_both_ Punycode encoded and percent-encoded characters:
1752
1753```js
1754const myURL = new URL('https://%CF%80.example.com/foo');
1755console.log(myURL.href);
1756// Prints https://xn--1xa.example.com/foo
1757console.log(myURL.origin);
1758// Prints https://xn--1xa.example.com
1759```
1760
1761[Punycode]: https://tools.ietf.org/html/rfc5891#section-4.4
1762[WHATWG URL]: #the-whatwg-url-api
1763[WHATWG URL Standard]: https://url.spec.whatwg.org/
1764[`Error`]: errors.md#class-error
1765[`JSON.stringify()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
1766[`Map`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
1767[`TypeError`]: errors.md#class-typeerror
1768[`URLSearchParams`]: #class-urlsearchparams
1769[`array.toString()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString
1770[`http.request()`]: http.md#httprequestoptions-callback
1771[`https.request()`]: https.md#httpsrequestoptions-callback
1772[`new URL()`]: #new-urlinput-base
1773[`querystring`]: querystring.md
1774[`url.domainToASCII()`]: #urldomaintoasciidomain
1775[`url.domainToUnicode()`]: #urldomaintounicodedomain
1776[`url.format()`]: #urlformaturlobject
1777[`url.href`]: #urlhref
1778[`url.parse()`]: #urlparseurlstring-parsequerystring-slashesdenotehost
1779[`url.search`]: #urlsearch
1780[`url.toJSON()`]: #urltojson
1781[`url.toString()`]: #urltostring
1782[`urlSearchParams.entries()`]: #urlsearchparamsentries
1783[`urlSearchParams@@iterator()`]: #urlsearchparamssymboliterator
1784[converted to a string]: https://tc39.es/ecma262/#sec-tostring
1785[examples of parsed URLs]: https://url.spec.whatwg.org/#example-url-parsing
1786[host name spoofing]: https://hackerone.com/reports/678487
1787[legacy `urlObject`]: #legacy-urlobject
1788[percent-encoded]: #percent-encoding-in-urls
1789[stable sorting algorithm]: https://en.wikipedia.org/wiki/Sorting_algorithm#Stability
1790