Guide
URL encoding explained (percent-encoding)
Learn why URLs use %XX escapes, which characters are reserved, how to encode query parameters correctly, and how to avoid double-encoding bugs.
A URL is a structured string: it has a scheme, host, path, query, and fragment, and certain characters carry structural meaning. URL encoding (also called percent-encoding) lets you put arbitrary text — spaces, slashes, ampersands, non-English letters — into a URL without those characters being mistaken for structure. Paste a value into the encoder above to see it escaped.
Why %XX exists
URLs were originally limited to a small, safe set of ASCII characters. Anything outside that set, or any character that has special meaning in a URL, is replaced by a percent sign followed by the character's byte value in hexadecimal:
space → %20
& → %26
? → %3F
/ → %2F
é → %C3%A9 (UTF-8 encodes é as two bytes)
A space becomes %20 because its ASCII byte is 0x20. Multi-byte UTF-8 characters become several
%XX pairs, one per byte.
Reserved vs unreserved characters
The URL specification splits characters into groups:
- Unreserved —
A–Z,a–z,0–9, and- _ . ~. These never need encoding and should be left alone. - Reserved — characters that delimit parts of a URL:
: / ? # [ ] @ ! $ & ' ( ) * + , ; =. These are fine when used as structure, but must be encoded when they appear as data.
The distinction is about role, not the character itself. A / separating path segments is
structure and stays raw. A / inside a filename you are passing as a query value is data and must
become %2F.
Encoding query parameters
The most common place to get this right is the query string. Consider building a search link for
the term cats & dogs:
Wrong: /search?q=cats & dogs
Right: /search?q=cats%20%26%20dogs
If you leave the & raw, the server reads it as a parameter separator and thinks you sent a second,
empty parameter. Encode each value independently, then assemble the query — never encode the
whole assembled URL, or you will escape the ?, &, and = that hold it together.
Space: %20 vs +
Two conventions for spaces coexist and cause confusion:
- In the path and in modern URI encoding, a space is
%20. - In a query string submitted as
application/x-www-form-urlencoded(classic HTML form posts), a space is encoded as+, and a literal+becomes%2B.
If you are unsure which applies, %20 is accepted everywhere. The +-for-space rule is specific
to form-encoded bodies and query strings, so only rely on it when you know the receiver expects
form encoding.
The double-encoding trap
Double-encoding is the most frequent URL bug. It happens when a value that is already encoded
gets encoded again, because the % itself is a reserved character:
"a b" encode once → "a%20b"
"a%20b" encode again → "a%2520b" ← %20 became %2520
The decoder then returns a%20b instead of a b. This usually creeps in when a value passes
through two layers that each "helpfully" encode it — a framework, then a manual call. To diagnose
it, decode the suspect string once: if you still see %XX sequences, it was encoded more than
once. The fix is to encode at exactly one well-defined boundary and never re-encode downstream.
Get three habits right — encode per component, treat reserved characters by role, and encode only once — and percent-encoding stops being a source of mysterious bugs. Use the encoder and decoder above to check any value before you drop it into a URL.