Loading URL Encoder & Decoder…
For a single query value, a path segment or a fragment. Escapes the delimiters as well.
Nothing entered yet.
Only unreserved characters survive untouched: # $ & + , / : ; = ? @ are the eleven that encodeURIComponent escapes and encodeURI does not. Both leave letters, digits and - _ . ! ~ * ' ( ) alone. Neither is enough on its own for an internationalised domain name, which needs Punycode rather than per-cent escapes.
Nothing is requested, fetched or logged: the text is transformed by JavaScript in your browser, which is why a URL with a session token in the query string is safe to paste here.
JavaScript ships two percent-encoders and they are not interchangeable. encodeURIComponent escapes the eleven delimiters as well as everything unsafe, which is correct for one value going into one slot. encodeURI leaves those delimiters alone, which is correct for an address already assembled. Choosing the wrong one produces a string that looks encoded and fails anyway, so this tool runs both on your own input and shows the difference.
Take https://example.com/search?q=café crème through encodeURI: the space becomes %20 and the accented letters %C3%A9 and %C3%A8, while the colon, slashes and question mark stay as they are. The result is a working URL.
Pass the same string through encodeURIComponent and you get https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Dcaf%C3%A9%20cr%C3%A8me — every structural character escaped, which no server will route because there is no longer a scheme, a host or a query in it.
Now the opposite error. The value a/b&c=d belongs in one parameter, so it must become a%2Fb%26c%3Dd. Encode it with encodeURI and the ampersand survives, the server splits on it, and one parameter becomes two with part of your value gone. Nothing errors; the data is simply wrong.
Percent-encoding works on bytes. A character outside ASCII becomes UTF-8 first, then each byte is written as a per-cent sign and two hex digits: é is two bytes and becomes %C3%A9, an emoji is four bytes and becomes four escapes. That is why encoded text can run several times longer than what went in.
Left alone by both are the unreserved characters — letters, digits, hyphen, underscore, full stop and tilde — plus the few JavaScript spares for historical reasons: exclamation mark, asterisk, brackets and the apostrophe.
Spaces have two encodings. %20 is correct everywhere; a plus sign means a space only in a form body, where the media type is application/x-www-form-urlencoded. In a path a plus is a literal plus, which is why that interpretation is a switch here rather than a guess — reading a path as a form body turns C++ into C followed by two spaces.
decodeURIComponent throws a URIError on anything malformed, which is the least useful behaviour possible when the reason you are decoding is to find the malformed part. Two cases cause it: a per-cent sign not followed by two hex digits, as in 100% cotton, and a run of escapes that is not valid UTF-8, such as a lone %C3 whose second byte was lost.
This decoder handles both without throwing. Everything it understands is decoded, anything it cannot is passed through exactly as written, and each problem is listed — so %41%zz%42 comes back as A%zzB with one complaint rather than an exception and an empty box.
The query-string breakdown applies the same rule per parameter. Paste a whole URL and each name and value gets a row, with repeated names pointed out, a name carrying no equals sign distinguished from one with an empty value, and any bad escape attributed to the parameter it sits in.
It does not apply to the host part of an address: an internationalised domain uses Punycode instead, so café.example becomes xn--caf-dma.example. Escapes in a hostname simply do not work.
It also conceals nothing. Escaping is reversible by anyone, this page included, so a query string is a poor place for a secret: it lands in server logs, in browser history, and historically in the Referer header. Everything here is computed in your own browser, and no address you paste is fetched or recorded.
encodeURIComponent for a single value you are inserting, encodeURI for a complete address you have already built. If you find yourself encoding a whole URL to put inside another URL, that inner one is a value, so it takes the component encoder.
Because a space was encoded twice: the first pass made %20, the second escaped the per-cent sign into %25 and left the 20 behind. Decoding once here leaves a literal %20 in the text, which is the tell that a value was encoded on the way in and again on the way out.
Yes, as %2F, or it reads as a path separator. Some servers and proxies reject or normalise encoded slashes in a path by default, so a value containing one usually belongs in the query string instead.
Yes — the transformation is local and nothing is sent anywhere, so this page adds no exposure. That token has already passed through an address bar and possibly a log, which is the more serious problem.