URLs may only contain a restricted set of ASCII characters. Everything else — spaces, accents, emoji, and the punctuation that URLs use structurally — has to be written as a percent sign followed by the byte value in hex. That is all percent-encoding is. The interesting part is knowing which characters to encode, because encoding too many breaks a URL just as thoroughly as encoding too few.
There are two encoders, and picking the wrong one breaks things
JavaScript gives you encodeURI and encodeURIComponent, and they differ by exactly eleven characters: # $ & + , / : ; = ? @. encodeURI leaves those alone; encodeURIComponent escapes them.
That list is not arbitrary — those are precisely the characters that mean something structural in a URL. The slash separates path segments, the question mark starts the query, the ampersand separates parameters, the hash begins the fragment. So the rule follows directly: use encodeURI when you have a whole URL and want to leave its skeleton intact. Use encodeURIComponent when you have one value that is about to be dropped into a URL — a single query parameter, one path segment.
Get it backwards and the failure is quiet. Encode an entire URL with encodeURIComponent and you get a string where https%3A%2F%2F is no longer a scheme, and nothing will fetch it. Encode a query value with encodeURI and a value containing & silently splits into two parameters — which is not just a bug, it is how query-parameter injection works. This tool escapes the full component set, which is the safe default for the common case: encoding a value.
The plus sign is not a space, except when it is
This is the subtlest trap in the whole subject, and it is genuinely ambiguous rather than merely confusing. In RFC 3986, the specification that governs URLs, a space is %20 and a plus is a literal plus. But HTML forms do not use RFC 3986 — they use application/x-www-form-urlencoded, an older convention in which a space is written as +.
The result is that the same string decodes two different ways depending on who is reading it. decodeURIComponent("a+b") returns "a+b", keeping the plus. new URLSearchParams("q=a+b").get("q") returns "a b", turning it into a space. Neither is wrong; they implement different specifications. This is why a search for "C++" so often arrives as "C " — something in the chain treated form-encoding rules as URL rules.
Practically: inside a query string, assume + means space, because that is what browsers and virtually every server framework assume. Anywhere else in a URL — a path segment, a fragment — a plus is a plus. The RFC 1738 checkbox on this page switches the output to the form-encoded convention for exactly this reason.
Why decoding "100%" throws an error
A percent sign is not an ordinary character in an encoded URL — it is an escape marker, and the decoder requires exactly two hex digits after it. Hand decodeURIComponent the string "100%" and it does not return "100%"; it throws URIError: URI malformed, because there is nothing after the percent to read.
This surfaces constantly with real data. Discount codes, statistics, anything containing a literal percent sign will break a decoder unless the percent was itself encoded as %25 on the way in. If you are seeing URIError on user-supplied data, the bug is almost always upstream: something built the URL by concatenating strings rather than by encoding each value properly.
Non-ASCII characters become several bytes each
Percent-encoding operates on bytes, not characters, and modern URLs carry UTF-8. So a character outside ASCII becomes one escape per byte: é is two bytes and encodes to %C3%A9, while an emoji is four bytes and becomes twelve characters of escape.
That is worth remembering when a length limit is involved. A path or parameter that looks comfortably short in Japanese or Arabic can be three times longer once encoded, and some systems still impose limits around 2000 characters for the whole URL.
Common questions
Is my URL sent to a server?
No. This tool is marked "client": the encoding runs in your browser tab and the text never leaves your machine. Worth noting because URLs from real systems often carry session tokens, API keys or customer identifiers in their query strings — if yours does, treat it as a credential regardless of which tool you paste it into.
Should I use + or %20 for a space?
%20 always works — it is valid in every part of a URL and every decoder understands it. + only means space inside a query string, and only under form-encoding rules. If you are unsure, use %20; it is never wrong. Use + only when you are deliberately producing form-encoded data and know the reader expects it.
My encoded URL has %2520 in it. What happened?
Double encoding. %25 is an encoded percent sign, so %2520 is what you get when %20 goes through an encoder a second time — the % became %25 and the 20 came along. Something in your pipeline is encoding a value that was already encoded. Encode exactly once, at the point where you build the URL, and never on a string you did not construct yourself.
Why is my ampersand splitting my parameter in two?
Because it was not encoded when the parameter value was built. In a query string, & is the separator between parameters, so a value containing a raw & is indistinguishable from the start of a new one. It needs to be %26. This is also the mechanism behind parameter injection, so it is worth fixing properly at the point where you build the URL rather than patching the symptom.
Do I need to encode a URL I got from a browser address bar?
Almost certainly not — it is already encoded, and encoding it again produces the %2520 problem above. Browsers display a decoded, readable version while holding the encoded one internally. What you see is not what is being sent. If a URL already contains % escapes, it has been encoded; decode it to read it, do not encode it again.