URL Encoding Explained: What %20 and %3A Really Mean
Every developer has seen %20 in a URL and wondered what it means. This guide covers percent-encoding, RFC 3986, the difference between encodeURI and encodeURIComponent, and when to use each.
Why URLs Need Encoding
URLs can only contain a limited set of ASCII characters defined by RFC 3986. Characters outside that set — spaces, accented letters, symbols like &, ?, # — have special meaning in URL syntax and would break the parser if used literally.
Percent-encoding (a.k.a. URL encoding) converts these characters to a safe representation: a % sign followed by the character's two-digit hexadecimal UTF-8 byte value.
// Raw string
Hello World & more!
// URL-encoded
Hello%20World%20%26%20more%21
Safe vs Reserved vs Unreserved Characters
A–Z a–z 0–9 - _ . ~
These are always safe in any URL position.
: / ? # [ ] @ ! $ & ' ( ) * + , ; =
Allowed literally in specific URL components, must be encoded when used as data.
Spaces, accents, CJK, emoji, symbols…
Must always be percent-encoded before inclusion in a URL.
encodeURI vs encodeURIComponent
JavaScript has two built-in functions, and picking the wrong one is a common bug:
encodeURI(url)
Encodes a complete URL. Leaves reserved characters (: / ? # @ ! $ & ' ( ) * + , ; =) alone because they have structural meaning in a full URL.
encodeURI("https://example.com/search?q=hello world&lang=en")
// → "https://example.com/search?q=hello%20world&lang=en"
// ↑ space encoded, but & and ? left alone ✅encodeURIComponent(value)
Encodes a component — a single query parameter, path segment, or fragment. Encodes everything including reserved characters, because the value might contain characters that would otherwise break the URL structure.
const query = "price >= 100 & category=books";
const url = `https://example.com/search?q=${encodeURIComponent(query)}`;
// → "https://example.com/search?q=price%20%3E%3D%20100%20%26%20category%3Dbooks"
// ↑ & encoded as %26 so it doesn't split the query string ✅Rule of thumb: use encodeURI for a full URL you're about to navigate to. Use encodeURIComponent for any value you're inserting into a URL.
Common Percent-Encoded Characters
| Character | Encoded | Note |
|---|---|---|
| %20 | Space — most common | |
| ! | %21 | |
| # | %23 | Fragment delimiter |
| $ | %24 | |
| & | %26 | Query param separator |
| ' | %27 | |
| ( | %28 | |
| ) | %29 | |
| + | %2B | Also used as space in form data |
| , | %2C | |
| / | %2F | Path separator |
| : | %3A | Scheme / port separator |
| ; | %3B | |
| = | %3D | Query param assignment |
| ? | %3F | Query string start |
| @ | %40 | |
| [ | %5B | |
| ] | %5D |
The + vs %20 Confusion
In application/x-www-form-urlencoded (HTML form submissions), a space is encoded as + instead of %20. This is a legacy convention from early HTML specs.
In modern URL encoding (RFC 3986), %20 is the correct encoding for a space. When in doubt — especially in query strings built with JavaScript — use encodeURIComponent, which always produces %20.
Encode and decode URLs instantly
Paste any URL or string to encode/decode it — supports both standard percent-encoding and form encoding.
Open URL Encoder →