URL Encoding Explained: How Percent-Encoding Works
Understand URL encoding (percent-encoding), when to encode and decode URLs, and how to handle special characters in query strings and paths.
URL encoding, also called percent-encoding, is the mechanism that allows URLs to contain characters beyond the basic ASCII set. Without it, a URL with spaces, Unicode, or special characters would break.
What Is URL Encoding?
URL encoding replaces unsafe characters with a % followed by two hexadecimal digits. For example:
- Space →
%20 @→%40&→%26- Newline →
%0A
The full form of URL encoding is percent-encoding, defined in RFC 3986.
Which Characters Need Encoding?
URLs can only contain a limited set of characters unencoded:
Unreserved (safe):
- Letters:
A-Z,a-z - Digits:
0-9 - Special:
-,_,.,~
Reserved (have special meaning):
:/?#[]@!$&'()*+,;=
Must always be encoded:
- Space,
<,>,",{,},|,\,^,`
Everything else should be encoded.
Query String vs Path Encoding
Not all parts of a URL are encoded the same way:
| Component | Encoding | Example |
|-----------|----------|---------|
| Path | / is literal, spaces → %20 | /tools/base64 |
| Query | & and = are separators | ?q=hello+world |
| Fragment | Not sent to server | #section-1 |
Query String Encoding
In query strings, + represents a space (legacy from application/x-www-form-urlencoded):
?q=hello+world ← + means space
?q=hello%20world ← %20 also means space
Modern practice prefers %20 over + for spaces.
Common Use Cases
Encoding User Input
Never put user input directly into a URL:
const query = "hello world & special chars";
const url = `https://api.example.com/search?q=${encodeURIComponent(query)}`;
// "https://api.example.com/search?q=hello%20world%20%26%20special%20chars"
Encoding a Full URL
const url = "https://example.com/path?q=hello";
const encoded = encodeURI(url);
// "https://example.com/path?q=hello" (keeps valid URL structure)
Decoding
const decoded = decodeURIComponent("hello%20world%20%26%20special");
// "hello world & special"
encodeURI vs encodeURIComponent
| Function | Encodes | Use Case |
|----------|---------|----------|
| encodeURI | Only unsafe chars, preserves URL structure | Encoding a complete URL |
| encodeURIComponent | Almost everything except A-Z a-z 0-9 - _ . ! ~ * ' ( ) | Encoding a single component (query param, path segment) |
const url = "https://example.com/path?name=John Doe";
encodeURI(url);
// "https://example.com/path?name=John%20Doe" (preserves URL)
encodeURIComponent(url);
// "https%3A%2F%2Fexample.com%2Fpath%3Fname%3DJohn%20Doe" (encodes everything)
Common Mistakes
-
Double encoding — encoding an already-encoded string gives
%2520instead of%20 -
Not encoding user input — always use
encodeURIComponentfor query parameters -
Using
+for spaces in paths — paths should use%20, not+ -
Forgetting to decode — server-side languages auto-decode query params; don't decode twice
-
Encoding
:and/in query values — these are safe inside query values, butencodeURIComponentencodes them anyway (which is fine)
Unicode and Non-ASCII Characters
Non-ASCII characters are first UTF-8 encoded, then each byte is percent-encoded:
é → UTF-8: 0xC3 0xA9 → %C3%A9
€ → UTF-8: 0xE2 0x82 0xAC → %E2%82%AC
Most modern APIs handle UTF-8 directly, but some legacy systems require explicit encoding.
Try It Now
Use our free URL Encoder/Decoder to encode and decode URLs instantly — with component vs full URL encoding modes.