PRACTICAL GUIDE
URL Encoding Explained: When to Escape and What Breaks
Why spaces become %20, when a plus sign means a space, and the one rule that prevents most broken links and injected parameters.
Last updated
Some characters have a job in a URL
A URL is a structured string. The question mark starts the query, the ampersand separates parameters, the equals sign splits a name from its value, the slash divides path segments, the hash begins the fragment. When one of those characters appears in your data rather than in the structure, it has to be escaped or the URL means something other than you intended.
Percent-encoding is the mechanism: the character is replaced by a percent sign and its byte value in hexadecimal. A space becomes %20, an ampersand becomes %26, a slash becomes %2F.
Encode the parts, never the whole
This is the rule that prevents most mistakes. Encode each parameter value on its own, then assemble the URL from the encoded pieces. Running an encoder over a complete URL destroys it, because the separators you needed get escaped along with everything else.
In JavaScript the distinction is encodeURIComponent, which escapes the separators and is what you want for a single value, versus encodeURI, which preserves them and is only for tidying a URL that is already correctly structured. Our encoder uses the component form.
Why a plus sign sometimes means a space
In the older form-submission encoding — the one HTML forms use by default, and the one that governs most query strings — a space is written as a plus sign, and a literal plus is written as %2B. In the path portion of a URL, a plus is just a plus and a space must be %20. This inconsistency is historical and permanent. It is also why a value containing a plus, such as an email address with a tag or a phone number in international format, so often arrives at the server with the plus turned into a space.
What does not need escaping
Letters, digits, and the characters hyphen, underscore, full stop and tilde are unreserved and always safe. Everything else is safer escaped. A few characters — exclamation mark, apostrophe, parentheses and asterisk — are left alone by the standard JavaScript function even though some servers treat them specially, so if you are constructing a URL for a system with strict expectations, check them.
Double encoding, and how to recognise it
If an already-encoded string is encoded again, the percent signs themselves get escaped: %20 becomes %2520. The tell-tale sign is a %25 in a URL where you expected something readable, or a page displaying a literal %20 instead of a space. It usually means a value was encoded once when it was created and once more when the URL was assembled, so remove one of the two rather than adding a decode step to compensate.
Do not put secrets in a query string
Encoding solves a syntax problem, not a privacy one. Query strings appear in browser history, in server access logs, in proxy logs, and in the referrer header sent to the next site the user visits. Tokens, passwords, identity numbers and personal data belong in a request body or a header, correctly encoded but out of the URL.
Frequently asked questions
Should I use encodeURI or encodeURIComponent?
encodeURIComponent for any individual value you are inserting into a URL. encodeURI only when you have a complete, already-structured URL and want to escape stray characters without touching the separators — which is a much rarer need than it sounds.
Why does my URL show %2520?
Double encoding. A string that already contained %20 was encoded again, turning its percent sign into %25. Find which of the two steps is redundant and remove it, rather than decoding twice at the other end.
Do I need to encode non-English characters?
In a URL, yes — they are encoded as their UTF-8 bytes, so a single accented letter becomes two percent-escapes. Browsers hide this by displaying the readable form in the address bar while sending the encoded one, which is why a link that looks fine can still be malformed underneath.
Is URL encoding a security measure?
No, but correct encoding does prevent a class of injection where a crafted value adds an extra parameter to your URL. It is a correctness measure with a security side effect, and it is never a substitute for validating input on the server.