URL encoding (percent-encoding)

Why spaces and symbols in a URL get turned into %20 and friends, and the difference between query and path encoding.

What percent-encoding is

URLs may only contain a limited set of characters from the ASCII set. Any character outside that set — or a reserved character used for its literal value — is encoded as a % followed by two uppercase hex digits representing its byte.

hello world      → hello%20world
c++ & c#        → c%2B%2B%20%26%20c%23
price=€10        → price%3D%E2%82%AC10   (€ is 3 UTF-8 bytes: E2 82 AC)

Why it exists

The URL grammar reserves characters such as ?, &, =, #, / for structure. If a value legitimately contains one of them, the parser must know it is data, not syntax. Encoding disambiguates.

💡
A space may be encoded as %20 almost everywhere, but in the application/x-www-form-urlencoded body used by HTML forms a space becomes a +. That is a different rule for a different context.

Encoding is over bytes, not characters

Modern URLs encode the UTF-8 bytes of the character, not the code point directly. é (U+00E9) is one UTF-8 byte 0xC3 0xA9, so it becomes %C3%A9. This is why the same character always encodes the same way regardless of the platform.

// JavaScript
const s = 'café';
const enc = encodeURIComponent(s); // "caf%C3%A9"
const dec = decodeURIComponent(enc);   // "café"

FAQ

What is the difference between encodeURI and encodeURIComponent?
encodeURIComponent encodes everything reserved (safe for a query value); encodeURI leaves characters like / ? # & intact (safe for a whole URL).
Why do I see + instead of %20?
That is the form-urlencoded convention for spaces inside request bodies, not in the URL path.

Base64 encoding UTF-8 and character sets

Last refreshed 2026-09-17.