Toolbox runs in your browser

Index / Developer

URL Encoder and Decoder

Percent-encoding, in the four conventions that disagree about which characters are safe. The page says which characters each one leaves alone, and shows the bytes it produced.

This page never puts what you type into its own address bar. A URL is one of the likeliest places to find a session token, a signed link or a password, and anything in the query string of this page would land in your browser history, in your bookmarks, and in the Referer header of the next link you clicked. So there is no shareable link here, deliberately. What you paste stays in this tab and goes nowhere.
What to do with it
Input
Pasted text is taken exactly as it is, including any newlines.
Output
Select it and copy. Nothing is sent anywhere and nothing is stored.
Ready
0

In --
Out --

The input, taken apart as a URL

Which characters each convention leaves alone RFC 3986 strict escapes everything except the 66 unreserved characters: A–Z a–z 0–9 - . _ ~. This is the one to use when the value is going into a path segment, and the one that never surprises a server.

encodeURIComponent is the same, plus five characters JavaScript leaves alone for historical reasons: ! ' ( ) *. They were “mark” characters in the older RFC 2396 and are sub-delimiters in RFC 3986, so a server is entitled to treat them as structure. If you are signing a request — AWS SigV4, OAuth 1.0 — this is the difference that breaks the signature, which is why both are offered here rather than one.

encodeURI is for a whole URL and therefore leaves the characters that give a URL its shape: ; , / ? : @ & = + $ # as well as the five above. It will not escape an & inside a value, so it is the wrong tool for encoding one parameter.

application/x-www-form-urlencoded is RFC 3986 strict with one difference that is 30 years old and still catches people: a space becomes +, not %20. Both decode to a space in a form field; only %20 decodes to a space in a path.

Everything is UTF-8. A character outside ASCII is turned into its UTF-8 bytes and each byte is escaped separately, so é is %C3%A9 — two escapes for one character. That is why the counts below are given in both characters and bytes.

Broken input is reported, not thrown away. A % that is not followed by two hex digits is left exactly as it is and counted. Bytes that are not valid UTF-8 become the replacement character � — one per malformed sequence, following the same rule as a browser — and are counted too. The browser's own decodeURIComponent throws on both, which tells you the string is broken but not where.