Three encodings, not one
encodeURIComponent, encodeURI and form encoding escape different sets of
characters, and picking the wrong one is the usual cause of a URL that works in
testing and breaks on real data.
| Mode | Escapes | Use it for |
| --- | --- | --- |
| Component | & = ? / # + space and everything non-ASCII | One query value or one path segment |
| Whole URL | non-ASCII only, structure untouched | A finished URL containing accents or Cyrillic |
| Form data | as component, but space becomes + | A application/x-www-form-urlencoded body |
Encode the parts, then assemble
The reliable order is: encode each value with component mode, then join them
with ?, & and = yourself. Encoding the assembled URL cannot work, because
by then the separators and the data look identical.
Where it bites
A customer name with an ampersand, a search term with a hash, a filename with a
space, a redirect parameter holding another URL. All four are ordinary inputs,
and all four break a hand-built query string that was only ever tested with
test123.
Questions
Which mode do I want?+
Component for a single query value or path segment — it escapes &, =, ? and / so they cannot be mistaken for structure. Whole URL when you have a complete address with non-ASCII characters and want the structure left alone. Form data when the value goes into an application/x-www-form-urlencoded body, where a space is + rather than %20.
Why did encoding my whole URL not escape the ampersand?+
Because in whole-URL mode the ampersand is structure — it separates parameters. If you encode a full URL that already contains a value with an & in it, the damage is already done: encode each value separately with component mode before assembling the URL.
What is the difference between %20 and +?+
Both mean a space, in different places. %20 is correct anywhere in a URL. The + convention applies only to form-encoded bodies and query strings written in that style, and a + inside a path stays a literal plus. Mixing them is how a search for "a+b" becomes a search for "a b".
Does this handle Cyrillic and emoji?+
Yes. The text is converted to UTF-8 bytes first and each byte is percent-encoded, which is what the specification requires. A single Cyrillic letter becomes two escapes, an emoji four.