URL Encoding Explained: When and Why Characters Are Percent-Encoded
Learn why URLs need encoding, how percent-encoding works, and when to use encodeURIComponent vs encodeURI in real applications.
You've seen %20 in a URL and wondered what it means. You've had a URL break in mysterious ways when it contained an ampersand. URL encoding is the unsung hero of the web — and the source of countless bugs when you misunderstand it.
What is URL encoding?
URL encoding (officially called percent encoding) is a way to represent characters in a URL that would otherwise have special meaning, or that aren't allowed at all. Each unsafe character is replaced with a percent sign followed by two hex digits representing its byte value.
space → %20 · & → %26 · ? → %3F · / → %2F · é → %C3%A9
The result is a URL that contains only ASCII letters, digits, and a small set of punctuation — guaranteed to survive transmission through any system that follows the HTTP and URI specs.
Try the encoder: Paste any string and see the encoded form instantly:
Open URL Encoder →Why do we need it?
URLs have a strict grammar. Specific characters separate components:
?separates the path from the query string&separates query parameters from each other=separates a parameter name from its value#introduces the fragment identifier/separates path segments
If your data contains any of these characters, it must be encoded. Otherwise the URL parser cannot tell where one part ends and the next begins.
Consider a search query for black & white. Without encoding, the URL ?q=black & white&page=1 would parse as three parameters: q=black , white, and page=1. With encoding, ?q=black%20%26%20white&page=1 parses correctly.
encodeURIComponent vs encodeURI
JavaScript provides two encoding functions, and the difference matters.
encodeURIComponent — escapes everything
Use this when you're encoding part of a URL — a query string value, a path segment, a fragment. It escapes ?, &, =, /, and almost everything else except letters, digits, and a handful of safe punctuation marks.
encodeURI — preserves URL structure
Use this when you have a complete URL that contains spaces or unicode characters, but where the URL structure (the slashes, query separators, etc.) should be preserved as-is.
Input: https://example.com/search?q=hello world
encodeURI: https://example.com/search?q=hello%20world
encodeURIComponent: https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Dhello%20world
Common pitfalls
- Double encoding: If you encode something twice (encode the encoded result), you get
%2520where you wanted%20. Decoding once returns the encoded form, not the original. This breaks form submissions and URL handlers in subtle ways. - Plus sign confusion: In query strings, historically
+meant a space (legacy from form submissions). ModernencodeURIComponentuses%20for spaces. If you need to handle legacy URLs, replace+with space before decoding. - Forgetting unicode: Non-ASCII characters like é, 中, 🚀 must be encoded as their UTF-8 byte sequence — multiple percent-escapes for a single character.
Practical examples
- Search forms:
?q=encodeURIComponent(userInput)— always encode user-provided search terms. - OAuth redirects:
redirect_uri=encodeURIComponent(callbackUrl)— the callback URL contains?and&that must not collide with the outer URL's structure. - API path with user IDs:
/users/${encodeURIComponent(id)}— protects against user IDs containing slashes.
When you can skip it
For URLs you control entirely (hardcoded paths to your own assets), you don't need to encode. The risk comes when any part of the URL is user-provided or dynamic. In that case, encode the dynamic part to be safe.