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