URL encoding explained: why spaces become %20 (or +), and what has to be escaped

A URL can only contain a limited set of characters, and everything else β€” spaces, accents, ampersands inside a value, emoji β€” has to be smuggled in as %XX codes. That is percent-encoding, the reason search links look like q=caf%C3%A9&lang=en, and it has a couple of rules that catch people every week. The URL encoder does the conversion; this guide explains when and why.

What a URL may contain

RFC 3986 defines the syntax. Letters, digits and - . _ ~ are unreserved and may appear anywhere. A set of reserved characters β€” : / ? # [ ] @ ! $ & ' ( ) * + , ; = β€” have meaning as delimiters: / separates path segments, ? starts the query, & separates parameters, # marks the fragment. Everything else (spaces, quotes, < >, control characters, any byte above 127) is not allowed literally. A reserved character used for its delimiter meaning stays as is; one that appears as data β€” an ampersand inside a search term β€” must be encoded, or the URL is parsed wrongly.

Percent-encoding

Each disallowed byte becomes a percent sign followed by its two-digit hexadecimal value: space is %20, ampersand %26, question mark %3F, slash %2F, percent itself %25. Decoding reverses it. Browsers encode automatically when you type a URL with a space, and JavaScript offers encodeURIComponent (encodes everything except unreserved characters β€” use it for query values) and encodeURI (leaves the delimiters alone β€” use it for a whole URL). Encoding a full URL with the component function breaks it, and encoding a value with the URI function leaves & and = unescaped: the commonest bug in link building.

%20 versus +

In a URL path, a space is %20. In the query string of an HTML form submitted with the default encoding (application/x-www-form-urlencoded), a space becomes + β€” a legacy of 1990s forms β€” and a literal plus becomes %2B. Both conventions coexist: a server decoding a form treats + as a space, while a path decoder treats + as a plus. When building a URL by hand, %20 is always safe; when reading one, know which part you're in. The UTM builder encodes parameter values so campaign names with spaces survive (UTM parameters explained: the five tags and how to use them consistently).

Non-ASCII text in URLs

Percent-encoding works on bytes, so text must first become bytes β€” in UTF-8, by the standard (UTF-8 explained: how text is stored, and why it turns into é and Ò€ℒ): Γ© is C3 A9, encoded as %C3%A9; a CJK character is three bytes, an emoji four. Browsers display decoded Unicode in the address bar for readability and encode it when you copy the link, which is why a pasted Wikipedia URL is full of percent signs. Domain names use a separate scheme (Punycode: mΓΌnchen.de becomes xn--mnchen-3ya.de) because DNS predates Unicode. The slug generator sidesteps the whole issue for page addresses by transliterating to ASCII (What a URL slug is, and the rules for a clean one).

Double encoding and other traps

  • Double encoding: encode an already-encoded value and %20 becomes %2520. Encode exactly once, at the point the value is placed in the URL.
  • Encoding the delimiters: %2F in a path is a literal slash inside a segment, not a separator; some servers reject it.
  • Fragments never reach the server: everything after # stays in the browser.
  • Length: browsers handle URLs of tens of thousands of characters, but some servers and proxies cap at 2–8 KB; long encoded values belong in a POST body.
  • Case: %3f and %3F are equivalent; the canonical form is uppercase.

The URL parser splits any link into scheme, host, path, query and fragment with each value decoded; Base64 is the other encoding people confuse with this one β€” it's for arbitrary bytes, not URL safety, though a URL-safe variant exists (What Base64 is, and what it is not).

Sources and further reading

The claims in this guide rest on these references, which were checked when the guide was last updated. Spotted an error? The contact page says how to report it.

  1. RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
  2. Percent-encoding β€” Wikipedia

Try the tool

Frequently asked questions

Why is there %20 in my URL?

It's an encoded space. Spaces aren't allowed in URLs, so they're written as the hex value of the space byte.

Is a space %20 or + in a URL?

%20 in paths and generally; + only in form-encoded query strings, where a real plus becomes %2B. When building URLs by hand, %20 is always safe.

Should I use encodeURI or encodeURIComponent?

encodeURIComponent for individual values (it escapes & = ? /); encodeURI for a complete URL you want to leave structurally intact. Mixing them up is the classic bug.

How are accented characters encoded in URLs?

As their UTF-8 bytes, each percent-encoded: Γ© β†’ %C3%A9. Browsers show the decoded form and encode on copy.