Form URL encoding 2026-11-05
Form URL encoding is the
application/x-www-form-urlencoded format for serializing an ordered list of name/value pairs. It is used by URLSearchParams and common form-processing conventions. Repeated names are allowed; the data model need not be a dictionary with one value per name.[ref]URL Standard by WHATWG. §5, format; §6.2, URLSearchParams
For example, the three pairs
Here the space becomes
("q", "a b+c"), ("tag", "x") and ("tag", "y") serialize as q=a+b%2Bc&tag=x&tag=y.Here the space becomes
+, while the literal plus in the value becomes %2B. Parsing the result recovers a b+c and both tag values. Replacing every plus with a space before deciding which encoding convention applies would misread data from other URL contexts.Structural separators must also be distinguished from value data. The encoded pair
q=a%26b has one value, a&b, rather than two pairs. The form parser first recognizes pair boundaries and then decodes their component data. Percent-encoding inside a component is consequently not an instruction to reinterpret the resulting characters as new separators.[ref]URL Standard by WHATWG. §5.1, split, plus replacement and percent-decoding steps
For modern serialization, text is encoded as UTF-8 bytes before the relevant bytes are percent-encoded. The name/value pair
("word", "café") therefore produces word=caf%C3%A9. This connects a text character with its byte representation rather than assigning one arbitrary percent code to the whole character.[ref] URLSearchParams 2026-11-05
URLSearchParams is an API for representing and manipulating an ordered list of name/value pairs, commonly obtained from a URL's query string. Repeated names are permitted. It uses form URL encoding, rather than imposing its interpretation on every conceivable query syntax.[ref]
URL API in the Node.js documentation. Class URLSearchParams, constructors and iteration
For
new URLSearchParams('tag=a&tag=b&q=a+b'), getAll('tag') returns both a and b, while get('q') returns a b. Calling set('tag','c') replaces the repeated entries with one: toString() then returns tag=c&q=a+b. An associative array holding just one value for each name would discard the original repeated-field information.A literal plus needs a different spelling. Appending the pair
q and a+b to a URL's searchParams produces query ?q=a%2Bb. The plus in the data is represented by percent-encoding, whereas the plus in q=a+b represents a space under this parser. These examples distinguish a character in a value from a character used by the encoding convention.[ref]URL API in the Node.js documentation. URLSearchParams.getAll, set, append and toString
URL serialization 2026-11-05
URL serialization produces the textual spelling of a structured URL record. It is the output side of processing that begins with a URL parser. The WHATWG serializer returns an ASCII string and can optionally omit the fragment identifier.[ref]
A worked example separates the stages. Constructing
new URL('https://EXAMPLE.org:443/a/../b?q=hello%20world~#top') gives href equal to https://example.org/b?q=hello%20world~#top. Lowercasing the host, removing the default port and resolving the parent-directory segment happen during parsing; the serializer exposes the resulting record.Now call
u.searchParams.sort() on that object. Even though there is only one query pair to sort, href becomes https://example.org/b?q=hello+world%7E#top. The decoded query value is unchanged, but URLSearchParams has rewritten its spelling using form URL encoding. Thus changing the query through an API can alter its percent-encoding without changing the value returned by that API.[ref]URL API in the Node.js documentation. url.searchParams: query-update and encoding caveat; URLSearchParams.sort