What Is URL Encoding?
URL encoding (also called percent-encoding) converts characters that are not allowed in URLs into a safe format. Each unsafe character is replaced by a % followed by its two-digit hexadecimal ASCII code.
Example:
Space → %20
& → %26
= → %3D
# → %23
So hello world & foo=bar becomes hello%20world%20%26%20foo%3Dbar.
Why Do URLs Need Encoding?
RFC 3986 defines URLs as a restricted character set. Characters fall into three categories:
| Category | Characters | Treatment |
|---|---|---|
| Unreserved | A–Z, a–z, 0–9, -, _, ., ~ |
Use as-is |
| Reserved | :, /, ?, #, [, ], @, !, $, &, ', (, ), *, +, ,, ;, = |
Special meaning in URL structure |
| Unsafe | Space, ", <, >, {, }, ` |
, `, ^, ``` |
If you include & literally in a query parameter value, the server interprets it as a parameter separator and your data breaks silently.
encodeURI vs encodeURIComponent
JavaScript provides two functions — knowing which to use is critical.
encodeURI(url)
Encodes a full URL. It does not encode characters that have structural meaning in URLs (:, /, ?, #, &, =).
encodeURI('https://example.com/search?q=hello world&lang=en');
// → 'https://example.com/search?q=hello%20world&lang=en'
// Notice: ?, &, = are NOT encoded — they keep their URL structure role
encodeURIComponent(value)
Encodes a single value (like a query parameter). It encodes everything except unreserved characters, including :, /, ?, #, &, =.
const query = 'C++ & Java: what's better?';
const url = 'https://example.com/search?q=' + encodeURIComponent(query);
// → 'https://example.com/search?q=C%2B%2B%20%26%20Java%3A%20what's%20better%3F'
Rule: Always use encodeURIComponent for values inside query strings. Use encodeURI only when encoding an entire pre-built URL that you don't want to break structurally.
URL Encoding in Other Languages
Python
from urllib.parse import quote, urlencode, quote_plus
# Encode a single value
quote("hello world & more") # → 'hello%20world%20%26%20more'
quote_plus("hello world") # → 'hello+world' (spaces as +, for form data)
# Encode query parameters
params = {'q': 'C++ guide', 'lang': 'en'}
urlencode(params) # → 'q=C%2B%2B+guide&lang=en'
PHP
// Encode a single value
urlencode("hello world & more"); // → 'hello+world+%26+more'
rawurlencode("hello world & more"); // → 'hello%20world%20%26%20more'
// Build a query string
http_build_query(['q' => 'C++ guide', 'lang' => 'en']);
// → 'q=C%2B%2B+guide&lang=en'
Go
import "net/url"
val := url.QueryEscape("hello world & more")
// → "hello+world+%26+more"
u := &url.URL{
Scheme: "https",
Host: "example.com",
Path: "/search",
RawQuery: url.Values{"q": {"C++ guide"}}.Encode(),
}
fmt.Println(u.String())
// → https://example.com/search?q=C%2B%2B+guide
Common Encoding Mistakes
Double-encoding
// WRONG: encode an already-encoded string
const val = encodeURIComponent("hello world"); // "hello%20world"
encodeURIComponent(val); // "hello%2520world" ← %25 is the encoding of %
Decode first, then re-encode if needed, or track whether a value is already encoded.
Not encoding at the right layer
Encode query parameter values only — not the entire URL. Encoding structural characters like ? or / in the full URL breaks routing.
Forgetting + vs %20
In query strings, + is often used as shorthand for a space (application/x-www-form-urlencoded format). Some parsers handle both; others don't. %20 is universally safe.
How to Decode URL Encoding
decodeURIComponent('hello%20world%20%26%20more');
// → 'hello world & more'
decodeURIComponent('C%2B%2B%20guide');
// → 'C++ guide'
In Python:
from urllib.parse import unquote
unquote('hello%20world%20%26%20more') # → 'hello world & more'
Frequently Asked Questions
Q: Is URL encoding the same as HTML encoding?
No. HTML encoding replaces characters like < with < to prevent XSS in HTML contexts. URL encoding uses %XX format. They serve different purposes.
Q: Should I encode the entire URL before making a fetch request?
No. Use URL and URLSearchParams to build URLs safely:
const url = new URL('https://example.com/search');
url.searchParams.set('q', 'C++ & Java');
url.searchParams.set('lang', 'en');
fetch(url.toString()); // Encoding handled automatically
Q: Why does my API return 400 when I have spaces in the URL?
Spaces in URLs are invalid. The HTTP spec requires them to be encoded as %20. Use encodeURIComponent on your query values.
→ Encode and decode URLs instantly with the URL Encoder/Decoder.