URLs · Encoding · Deep dive

URL Encoding Explained

Three encode modes, one bytes-to-characters rule, and a surprising number of ways to break URLs. Here is the full picture.

encodeURIComponent (aggressive)
https://example.com/search?q=hello world&tag=café
→
https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Dhello%20world%26tag%3Dcaf%C3%A9
encodeURI (preserves structure)
https://example.com/search?q=hello world&tag=café
→
https://example.com/search?q=hello%20world&tag=caf%C3%A9

The Core Rule

URL characters are limited to A–Z a–z 0–9 plus a handful of symbols. Anything else must be percent-encoded: each byte of the UTF-8 representation becomes %XX, where XX is the hex value of the byte.

Three Encode Modes in JavaScript

  • encodeURIComponent — encodes everything except A–Z a–z 0–9 - _ . ! ~ * ' ( ). Use this for query values and path segments.
  • encodeURI — leaves URL-structural characters alone (:/?#[]@!$&'()*+,;=). Use for whole URL strings where you want to keep the scheme, host, and separators intact.
  • form-urlencoded — like encodeURIComponent but spaces become +. HTML form submissions use this.

Reserved vs Unreserved (RFC 3986)

Unreserved characters never need encoding. Reserved characters (: / ? # [ ] @ ! $ & ' ( ) * + , ; =) have special meaning in the URL grammar and must be encoded when used literally in a value.

Common Mistakes

  • Double-encoding: encoding an already-encoded string turns %20 into %2520
  • Using encodeURI on a query value: & and = leak through and break parsing
  • Forgetting UTF-8: non-ASCII must be encoded as UTF-8 bytes, not Latin-1
  • Mixing + and %20: query strings accept both for spaces; be consistent

Try It

Encode or decode any string in your browser with our free URL Encoder and URL Decoder.

Encode values, not URLs

Use encodeURIComponent for query values; encodeURI for whole URLs.

Always UTF-8

Non-ASCII goes in as UTF-8 bytes before percent-encoding.

Encode once

Double-encoding is a top-10 production bug source.