Skip to main content

← Back to blog

URL Encoding Explained: Percent-Encoding, Query Strings & Broken Links

Ever pasted a link and seen %E4%B8%AD where a word should be, or had a query parameter mysteriously break? That’s URL encoding at work. Understanding it turns those cryptic strings into something you can reason about.

Why URLs need encoding

A URL may only contain a limited set of ASCII characters. Anything else — spaces, non-ASCII text, or characters that have special meaning like ?, &, #, / — must be percent-encoded: replaced by a % followed by the byte’s two-digit hex value. For example, a space becomes %20 and (UTF-8) becomes %E4%B8%AD.

You can encode or decode any string instantly with a URL encoder.

Reserved vs. unreserved characters

  • Unreserved characters (A–Z a–z 0–9 - _ . ~) never need encoding.
  • Reserved characters (: / ? # [ ] @ ! $ & ' ( ) * + , ; =) have structural meaning in a URL. Whether you encode them depends on context — inside a value they must be encoded; as structure they must not.

This is the heart of the encodeURIComponent vs. encodeURI distinction.

encodeURIComponent vs. encodeURI

  • encodeURIComponent encodes reserved characters too. Use it for a single value — one query parameter, one path segment.
  • encodeURI leaves reserved structural characters (/ ? & =) intact. Use it for an entire URL you don’t want to break apart.
encodeURIComponent("a b&c=d") // "a%20b%26c%3Dd"  ✅ safe as a value
encodeURI("https://x.com/a b") // "https://x.com/a%20b"  ✅ whole URL

Picking the wrong one is a top source of bugs: use encodeURI on a value and the & inside won’t be escaped, corrupting your query string.

%20 vs. +

Both can represent a space, but in different contexts. In a URL path and modern query strings the standard is %20. The + for a space comes from the older application/x-www-form-urlencoded format used by HTML form submissions. When in doubt, %20 is the safe, universal choice — and it’s what our tool produces.

The classic double-encoding bug

If a string is encoded twice, %20 becomes %2520 (because the % itself gets encoded to %25). Symptoms: literal %20 showing up in the browser, or spaces turning into %2520. The fix is to encode exactly once — decode first if you’re unsure of the input’s state. A decoder makes it easy to inspect what you actually have.

Quick reference

  • Encoding a parameter value? → encodeURIComponent.
  • Encoding a whole URL? → encodeURI.
  • See a stray %XX? → decode it to read the original.

Encode and decode URLs and query parameters instantly with the free URL encoder / decoder — it runs locally in your browser.