Skip to the tool

URL Encoder & Decoder

MDV Tools

Type text or a percent-encoded string on either side; the other side follows.

Runs on this device Works offline
encoding
type on either side
How this works

Percent-encoding writes each byte a URL cannot carry as % and two hex digits. Text is first turned into UTF-8 bytes, so é becomes %C3%A9. The three buttons are three sets of characters left alone. Query value or path part is encodeURIComponent: letters, digits and - _ . ! ~ * ' ( ) stay, and everything else is escaped, including & = ? / #, so a value cannot break the URL around it. Whole URL is encodeURI: it also keeps the characters that give a URL its shape, ; , / ? : @ & = + $ #, so it only fixes spaces and non-ASCII in a URL that is already put together, and it cannot tell a & inside a value from one between values. Form data follows the WHATWG application/x-www-form-urlencoded rule used by URLSearchParams and HTML forms: only letters, digits and * - . _ stay, and a space is written +.

Decoding reads the same way back. Every % must be followed by two hex digits, and a run of escapes must spell complete UTF-8; the first place either fails is named with its position and nothing is decoded. Whole URL leaves escapes of ; , / ? : @ & = + $ # as they are, as decodeURI does, because turning %2F into / would change the URL's structure. In Form data a + is a space; in the other two it is a plus sign. When the decoded text still holds escapes such as %20, the input was encoded twice, and the page says so.

What it does not do: it does not split a URL into its parts, does not turn a non-ASCII domain into its xn-- form (it percent-encodes it, which browsers do not use for host names), and does not change line breaks, so a form a browser submits, which sends CRLF, can differ from this output by those. A lone half of a surrogate pair has no UTF-8 form and is refused with its position. Each field takes up to 2,000,000 characters, and a result that would pass that is refused rather than written. Nothing is uploaded: there is no server in this file, and neither field is stored anywhere.

The Dark button remembers its setting in this browser's local storage. Nothing you type or drop into the page is stored.