You paste a URL into your browser and it looks like this:
https://example.com/search?q=hello%20world&filter=price%3E100
What are all those %20 and %3E symbols? Why does a space become %20? And why does > become %3E?
This is URL encoding (also called percent-encoding), and understanding it will save you from a category of bugs that trips up developers at every experience level.
Why URLs cannot contain raw special characters
A URL is a string of ASCII text with strict rules about which characters are allowed. Characters like spaces, #, ?, &, =, and > all have specific meanings in URL structure. If you include them literally in a query parameter, the browser or server will misinterpret the URL.
For example, this URL is ambiguous:
https://example.com/search?q=cats & dogs
Does the space end the URL? Is & another parameter separator? The parser cannot tell.
URL encoding solves this by replacing unsafe characters with a % sign followed by the character's two-digit hexadecimal ASCII code.
The encoding table (most common characters)
| Raw character | Encoded | Notes |
|---|---|---|
| Space | %20 |
Also sometimes encoded as + in form data |
+ |
%2B |
Literal plus sign in query strings |
= |
%3D |
Equals sign inside a value |
& |
%26 |
Ampersand inside a value |
# |
%23 |
Hash inside a path or query |
/ |
%2F |
Forward slash inside a value |
: |
%3A |
Colon inside a value |
? |
%3F |
Question mark inside a value |
@ |
%40 |
At sign |
< |
%3C |
Less-than |
> |
%3E |
Greater-than |
" |
%22 |
Double quote |
{ |
%7B |
Left curly brace |
} |
%7D |
Right curly brace |
Two modes you need to know
Full URL encoding
Encodes everything except letters, digits, and -_.~. Use this when encoding an entire URL for transport (e.g. embedding one URL inside another as a query parameter).
encodeURIComponent("https://example.com/path?q=hello world")
// → "https%3A%2F%2Fexample.com%2Fpath%3Fq%3Dhello%20world"
Query string value encoding
Only encodes the characters that would break a query string. Use this for encoding individual parameter values. In JavaScript, encodeURIComponent() is the right function — not encodeURI(), which leaves structural characters like ? and & untouched.
// WRONG — encodeURI leaves = and & unencoded
encodeURI("price=100&color=red&blue")
// RIGHT — encodeURIComponent encodes everything unsafe
encodeURIComponent("price=100&color=red&blue")
// → "price%3D100%26color%3Dred%26blue"
Common mistakes
1. Double-encoding
If you encode an already-encoded URL, %20 becomes %2520 (because % itself gets encoded to %25). Always decode first, then re-encode if needed.
2. Using encodeURI instead of encodeURIComponent
encodeURI is designed for full URLs. It will not encode :, /, ?, #, &, or =. For individual query parameter values, always use encodeURIComponent.
3. Forgetting that + means space in form data
When a form is submitted with method="GET", browsers encode spaces as + rather than %20. PHP's urldecode() handles both; JavaScript's decodeURIComponent does not handle + as a space. You need to replace + with %20 first if you are decoding form data in JavaScript.
function decodeFormValue(str) {
return decodeURIComponent(str.replace(/\+/g, '%20'));
}
How to decode a messy URL quickly
Instead of manually translating each %XX code, use a URL decoder tool. Paste the encoded URL, get the readable version instantly.
👉 URL Encoder / Decoder — SnappyTools
It handles both full URL encoding and query string encoding modes, shows the decoded output in real time, and works entirely in your browser — nothing is sent to a server.
TL;DR
- URLs can only contain safe ASCII characters; special characters must be percent-encoded
-
%20= space,%26=&,%3D==,%2F=/ - Use
encodeURIComponent()(notencodeURI()) for query string values in JavaScript - Watch out for double-encoding and the
+= space convention in form data
Have a URL that is not decoding correctly? Drop the encoded string in the comments and I will help you debug it.
Top comments (0)