URL Encode & Decode

Percent-encode or decode URLs and query strings. See the difference between encodeURI and encodeURIComponent. Runs in your browser.

Mode

What percent-encoding is

URLs can only contain a limited set of characters. Anything else is replaced with a % followed by two hex digits. A space becomes %20 and a slash becomes %2F.

https://example.com/a b?x=hello world
https://example.com/a%20b?x=hello%20world

The two functions, and when to use each

JavaScript gives you two, and mixing them up is a classic source of bugs.

FunctionEscapesLeaves intactUse for
encodeURIReserved characters/ ? # $ & + , ; = : @A whole URL
encodeURIComponentEverything except A-Z a-z 0-9 - _ . ! ~ * ' ( )Nothing but unreservedA single value

The rule of thumb: encodeURI for a complete URL, encodeURIComponent for a value going into it.

// Correct - a value inside a query string
url += "?q=" + encodeURIComponent(userInput);

// Wrong - breaks the URL structure
url += "?q=" + encodeURI(userInput);

If a user types & into a search box and you used encodeURI, the & stays literal and the query string splits in the wrong place. encodeURIComponent escapes it to %26 and the parameter stays intact.

The unreserved characters

RFC 3986 defines these as safe in any context:

A-Z  a-z  0-9  -  _  .  ~  !  *  '  (  )

Everything else gets escaped by encodeURIComponent.

The + gotcha

In a query string, a space can be written as %20 or +. In a path, only %20 is valid — + is a literal plus sign there. URLSearchParams encodes spaces as +, which is why new URLSearchParams({q: "a b"}).toString() gives q=a+b.

const p = new URLSearchParams({ q: "a b", tag: "c&d" });
// q=a+b&tag=c%26d

Common errors this fixes

  • % followed by non-hex — the result is a malformed URL that many servers reject
  • Unescaped & in a parameter value — extra parameters appear out of nowhere
  • Unescaped # in a value — everything after it is treated as a fragment and lost
  • Raw spaces in a URL — most browsers auto-escape them, but not every context does

Related

Encoding a whole payload rather than a URL? The Base64 encoder handles binary data safely.

Frequently asked questions

Is my text uploaded anywhere?

No. Encoding and decoding both run in your browser using the built-in URL APIs. Nothing is transmitted.

Should I use encodeURI or encodeURIComponent?

Use encodeURI for a complete URL and encodeURIComponent for a single value going into one. The difference is that encodeURI leaves reserved characters like &, ? and / intact.

Why is my space encoded as a plus sign?

In a query string, + is a valid way to encode a space and is what URLSearchParams produces. In a path segment, only %20 is valid — + there is a literal plus sign.

Why does decoding fail on some input?

A % must be followed by two hex digits. If a string contains a bare % or an invalid escape, it is malformed and cannot be decoded.

Can this handle non-ASCII text?

Yes. Characters outside ASCII are encoded as UTF-8 bytes first, then each byte is percent-escaped, so accented characters and emoji survive a round trip correctly.