URL Encoder & Decoder Guide: Percent-Encoding Explained
Technical Mastery Overview
Why URLs Need Encoding
URLs are restricted to a specific set of characters. The RFC 3986 specification defines two categories:
Unreserved characters — safe anywhere in a URL, no encoding needed:
A–Z a–z 0–9 - _ . ~
Reserved characters — have structural meaning in URLs and must be encoded when used as data:
: / ? # [ ] @ ! $ & ' ( ) * + , ; =
Everything else — spaces, accented characters, emoji, brackets, quotes — must be percent-encoded.
How Percent-Encoding Works
Each byte of the character is represented as %XX where XX is the hexadecimal value:
| Character | UTF-8 bytes | Encoded |
|---|---|---|
| Space | 0x20 |
%20 |
& |
0x26 |
%26 |
= |
0x3D |
%3D |
# |
0x23 |
%23 |
+ |
0x2B |
%2B |
é |
0xC3 0xA9 |
%C3%A9 |
😊 |
0xF0 0x9F 0x98 0x8A |
%F0%9F%98%8A |
Multi-byte UTF-8 characters produce multiple percent-encoded pairs — that's why emoji can take 12+ characters when encoded.
The Most Common Bug: Unencoded Query Parameters
https://api.example.com/search?q=hello world&filter=type=user&sort=date
This URL has three problems:
- Space in
hello world— breaks the URL at the space =inside thefiltervalue — looks like a new key-value pair&separatingfiltervalue fromsort— splits the parameter mid-value
Correctly encoded:
https://api.example.com/search?q=hello%20world&filter=type%3Duser&sort=date
Now the parser correctly reads:
q=hello worldfilter=type=usersort=date
encodeURIComponent vs encodeURI — Know the Difference
JavaScript has two encoding functions and confusing them is a very common mistake:
encodeURI("https://example.com/path?q=hello world&x=a=b")
// → "https://example.com/path?q=hello%20world&x=a=b"
// Encodes spaces but NOT :, /, ?, &, = — they're structural to the URL
encodeURIComponent("hello world&x=a=b")
// → "hello%20world%26x%3Da%3Db"
// Encodes EVERYTHING including &, =, /, ? — treats input as a raw value
Rule: use encodeURIComponent for individual parameter values, encodeURI for full URLs you want to escape just enough for safe transmission.
// Build a search URL correctly
const query = "C++ programming & algorithms";
const url = `https://api.example.com/search?q=${encodeURIComponent(query)}`;
// → "https://api.example.com/search?q=C%2B%2B%20programming%20%26%20algorithms"
The + vs %20 Space Ambiguity
Two different encodings for spaces exist:
%20— standard percent-encoding, works everywhere+— only valid inapplication/x-www-form-urlencoded(HTML form submissions)
HTML forms use + for spaces; URLs use %20. Mixing them causes bugs:
// In a URL query string: %20 is correct
const url = `https://example.com/search?q=hello%20world`;
// In a form body: + is conventional (and what browsers send)
// application/x-www-form-urlencoded: q=hello+world
When you see + in a URL and decode it with decodeURIComponent, the + is NOT converted to a space — only %20 is. Use decodeURIComponent(str.replace(/\+/g, ' ')) when decoding form-encoded strings.
Encoding for Different URL Positions
Different parts of a URL have different encoding requirements:
| URL part | What to encode | Function |
|---|---|---|
| Full URL | Minimal (just spaces and illegal chars) | encodeURI() |
| Query parameter value | Everything reserved | encodeURIComponent() |
| Path segment | Everything except / separators |
Custom or libraries |
Fragment (#...) |
Reserved chars | encodeURIComponent() |
| Username / password | Reserved chars | encodeURIComponent() |
Our encoder applies the correct encoding for query parameter values — the most common use case.
Decoding — Reading Encoded URLs
When you receive an encoded URL (from a webhook, a log entry, an OAuth callback), decoding it reveals the original parameters:
/callback?code=4%2F0AfJohXl7g&state=abc%3D123&error=access_denied
↓ decode ↓
/callback?code=4/0AfJohXl7g&state=abc=123&error=access_denied
Decode any encoded URL with our tool to read it clearly. Useful when:
- Debugging OAuth callback URLs
- Reading webhook
target_urlvalues from API responses - Interpreting log entries with encoded URLs
- Understanding redirect chains
Security: Open Redirects and Encoding Attacks
Improper URL handling creates security vulnerabilities:
Open redirect via encoding
https://app.example.com/redirect?url=https://evil.com
// vs
https://app.example.com/redirect?url=https%3A%2F%2Fevil.com
If your server decodes the url parameter and redirects without validation, both forms can redirect to evil.com. Always validate redirect destinations against an allowlist, regardless of encoding.
Path traversal via double-encoding
/files/..%2F..%2Fetc%2Fpasswd
Some servers decode this to /files/../../etc/passwd and serve sensitive files. Always normalize and validate paths after decoding, not before.
Building API Request URLs
When constructing URLs for our cURL Generator, encode each query parameter value separately before concatenating:
# Build URL with encoded parameters
QUERY=$(python3 -c "import urllib.parse; print(urllib.parse.quote('user@example.com'))")
curl "https://api.example.com/users?email=$QUERY"
Or let the HTTP library handle it:
const params = new URLSearchParams({
email: 'user@example.com',
role: 'admin & manager'
});
fetch(`/api/users?${params}`);
// Automatically encodes → /api/users?email=user%40example.com&role=admin+%26+manager
URLSearchParams uses + for spaces (form encoding convention) — if your API expects %20, convert after: .toString().replace(/\+/g, '%20').
Experience it now.
Use the professional-grade URL Encoder/Decoder with zero latency and 100% privacy in your browser.