A URL can only contain a limited set of characters. Letters (A–Z, a–z), digits (0–9), and a handful of special characters (-, _, ., ~) are "unreserved" and can appear in a URL as-is. Everything else — spaces, punctuation, non-ASCII characters, and characters with special meaning in URL syntax — must be encoded before they can be safely included.
URL encoding (officially called percent-encoding) is the mechanism that handles this. It replaces each unsafe character with a % sign followed by the character's two-digit hexadecimal byte value.
How Percent-Encoding Works
A space has the ASCII code 32, which is 20 in hexadecimal. So a space becomes %20:
"hello world" → "hello%20world"
An @ symbol has the ASCII code 64 (hex 40), so it becomes %40. An ampersand & is %26. A forward slash / is %2F.
For non-ASCII characters (like accented letters or emoji), the character is first converted to its UTF-8 byte sequence, and then each byte is percent-encoded:
"café" → "caf%C3%A9"
"🔥" → "%F0%9F%94%A5"
Reserved vs. Unreserved Characters
URL syntax assigns special meaning to certain characters:
?marks the start of a query string&separates query parameters=separates parameter names from values#marks a fragment identifier/separates path segments
When these characters appear as data rather than as URL structure, they must be encoded. For example, if a query parameter value contains an &, leaving it unencoded would confuse the parser into treating it as a parameter separator.
Unencoded: ?name=Tom & Jerry&format=json
Parsed as: name = "Tom " and " Jerry" and "format" = "json" ← wrong
Encoded: ?name=Tom%20%26%20Jerry&format=json
Parsed as: name = "Tom & Jerry", format = "json" ← correct
Query Strings and Form Submissions
HTML forms use a closely related encoding called application/x-www-form-urlencoded. It works like percent-encoding but also encodes spaces as + instead of %20. This is a legacy convention from early web forms, and you'll still see it in form POST bodies and some older APIs.
When working with query parameters in code, always use your language's built-in URL encoding functions rather than manually constructing strings. In JavaScript that's encodeURIComponent() for parameter values and encodeURI() for full URLs:
encodeURIComponent("Tom & Jerry") // "Tom%20%26%20Jerry"
encodeURI("https://example.com/search?q=hello world")
// "https://example.com/search?q=hello%20world"
Decoding
Percent-decoding reverses the process — %20 becomes a space, %26 becomes &, and so on. Browsers do this automatically when displaying URLs in the address bar. Servers decode incoming request URLs before routing them to application handlers.
Common Encoding Mistakes
Double-encoding happens when already-encoded strings get encoded again. %20 becomes %2520 (where %25 is the encoding for the % character). This usually results in broken links or garbled data.
Encoding too much or too little: encodeURI() leaves structural URL characters (/, ?, &, =) intact, making it safe for full URLs. encodeURIComponent() encodes those characters too, making it the right choice for individual parameter values.
To encode or decode URL strings directly in your browser, use the URL Encoder / Decoder. To generate clean, URL-safe slugs from any text, use the URL Slug Generator.