URL Encode & Decode — Percent Encoding Explained
URL encoding (also called percent encoding) converts characters that are not allowed in a URL into a safe format using a % followed by two hexadecimal digits. It's required whenever you embed user input, file names, or special characters in a URL.
What is URL encoding?
URLs can only contain a limited set of ASCII characters. Any character outside that set — spaces, accented letters, symbols, non-Latin scripts — must be percent-encoded before being placed in a URL. Each byte of the character is represented as %XX, where XX is the hexadecimal byte value.
Space → %20
/ → %2F
? → %3F
# → %23
& → %26
= → %3D
+ → %2B
@ → %40
é → %C3%A9 (UTF-8: two bytes)URL encoding in JavaScript
JavaScript provides two pairs of functions for URL encoding, each with different scope:
// encodeURIComponent — encode a single value (recommended for query params)
encodeURIComponent('hello world') // "hello%20world"
encodeURIComponent('a=1&b=2') // "a%3D1%26b%3D2"
encodeURIComponent('https://x.com') // "https%3A%2F%2Fx.com"
// decodeURIComponent — reverse of the above
decodeURIComponent('hello%20world') // "hello world"
decodeURIComponent('%C3%A9l%C3%A8ve') // "élève"
// encodeURI — encode a full URL (preserves :, /, ?, #, &, =)
encodeURI('https://example.com/path with spaces?q=hello world')
// "https://example.com/path%20with%20spaces?q=hello%20world"
// decodeURI — reverse of encodeURI
decodeURI('https://example.com/path%20with%20spaces')
// "https://example.com/path with spaces"Use encodeURIComponent for individual query parameter values. Use encodeURI only for complete URLs where you want to preserve the URL structure characters.
Encode query parameters correctly in JavaScript
// Wrong — encodes the = and & signs, breaking the URL structure
const bad = encodeURIComponent('https://api.example.com/search?q=hello world&lang=en')
// Correct — encode only the values
const q = encodeURIComponent('hello world')
const lang = encodeURIComponent('en')
const url = `https://api.example.com/search?q=${q}&lang=${lang}`
// "https://api.example.com/search?q=hello%20world&lang=en"
// Even better — use URLSearchParams
const params = new URLSearchParams({ q: 'hello world', lang: 'en' })
const url2 = `https://api.example.com/search?${params}`
// "https://api.example.com/search?q=hello+world&lang=en"
// Note: URLSearchParams uses + for spaces, not %20URL encoding in Python
from urllib.parse import quote, unquote, urlencode, quote_plus, unquote_plus
# Encode a single value (safe='/' keeps slashes unencoded)
quote('hello world') # 'hello%20world'
quote('hello world', safe='') # 'hello%20world'
quote('/path/to/file') # '/path/to/file' (/ preserved by default)
quote('/path/to/file', safe='') # '%2Fpath%2Fto%2Ffile'
# Decode
unquote('hello%20world') # 'hello world'
unquote('%C3%A9l%C3%A8ve') # 'élève'
# Encode query parameters (uses + for spaces, like HTML forms)
quote_plus('hello world') # 'hello+world'
unquote_plus('hello+world') # 'hello world'
# Encode a full query string from a dict
params = {'q': 'hello world', 'lang': 'en', 'page': 1}
urlencode(params) # 'q=hello+world&lang=en&page=1'%20 vs + for spaces
Spaces can be encoded as either %20 or +, depending on context:
| Context | Space encoding | Function |
|---|---|---|
| URL path segments | %20 | encodeURIComponent |
HTML form submissions (application/x-www-form-urlencoded) | + | URLSearchParams |
| Query strings (general) | Either (prefer %20) | — |
Modern APIs and browsers accept both, but %20 is more universally safe.
Characters that do NOT need encoding
These characters are safe in URLs and are left unencoded by encodeURIComponent:
A–Z a–z 0–9 - _ . ! ~ * ' ( )All other characters — including /, ?, #,&, =, +, and any non-ASCII characters — are encoded when passed through encodeURIComponent.
Common URL encoding mistakes
- Double-encoding — encoding an already-encoded string produces
%2520instead of%20. Always decode before re-encoding. - Using
encodeURIon values — it preserves=and&, so query parameter values with those characters won't be properly escaped. - Not encoding Unicode — characters outside ASCII must be UTF-8 encoded first, then percent-encoded. Modern functions handle this automatically.
Decode a URL online
Paste any percent-encoded URL or string into the URL Encode / Decode tool to instantly encode or decode it. For Base64-encoded strings (common in JWTs and data URIs), use the Base64 tool instead.