Developer tools

URL encoder and decoder

Encode text so it can go safely into a URL, decode a percent-encoded link back into readable text, and see any URL split into its host, path and query parameters. Encoding follows the same rules as JavaScript and HTML forms, and decoding tells you exactly which character is broken.

Runs entirely in your browser. Nothing you enter here is uploaded.

How to encode or decode a URL

  1. Choose Encode or Decode.
  2. When encoding, pick what the text is for. Use a query value or path segment for anything you will put between = and & or between two slashes — this is the right choice nine times out of ten. Use a whole URL only when you have a complete address that contains spaces or non-English characters and must keep its slashes and question mark. Use form data to match what an HTML form sends.
  3. Type or paste the text. The result updates as you type; press Copy to take it.
  4. When decoding, paste the encoded text or the whole link. Tick Treat + as a space if it came from a form submission or a search URL. If the text contains a stray % that is not an escape, tick Keep invalid % as it is instead of fixing it by hand.
  5. Whenever the input is a full URL, the Parts of this URL panel lists the scheme, host, port, path, fragment and every query parameter, decoded, one per row.

How percent-encoding works

A URL may only contain a limited set of ASCII characters, and some of those have jobs: / separates path segments, ? starts the query, & and = separate parameters, # starts the fragment. RFC 3986 defines how to include anything else: convert the text to UTF-8 bytes and write each byte as % followed by two hexadecimal digits. A space becomes %20; é, two bytes in UTF-8, becomes %C3%A9; a Chinese character, three bytes, becomes three escapes.

Why there are three modes

The difference is which characters are left alone. encodeURIComponent encodes everything except letters, digits and - _ . ! ~ * ' ( ), so a value containing & or / cannot break the URL it is placed in. encodeURI additionally leaves the structural characters ; , / ? : @ & = + $ # untouched, because it assumes you are encoding a complete URL. Using encodeURI on a single value is a classic bug: a value of "a&b" stays "a&b" and is read back as two parameters.

Form encoding (application/x-www-form-urlencoded, defined in the WHATWG URL Standard) is what browsers send for HTML forms and what URLSearchParams produces. It writes spaces as + and also encodes ! ' ( ) ~. That is why a search URL often shows q=hello+world, and why a literal plus sign in form data has to be sent as %2B.

Decoding precisely

JavaScript's decodeURIComponent throws a bare "URI malformed" error on bad input without saying where. This tool decodes the escapes itself: it collects consecutive %XX bytes and checks them as UTF-8, so it can report either an escape that is not followed by two hex digits or a multi-byte character that was cut off — usually the result of truncating a URL in the middle of a character.

International domain names

Host names are not percent-encoded. Non-ASCII domains are converted to Punycode, defined in RFC 3492, with an xn-- prefix. The parts panel shows both forms so you can see that 例子.com and xn--fsqu00a.com are the same host.

Examples

InputModeResult
a b&c=d/équery valuea%20b%26c%3Dd%2F%C3%A9
https://example.com/a b?q=1&r=é#xwhole URLhttps://example.com/a%20b?q=1&r=%C3%A9#x
a b+cform dataa+b%2Bc
it's (fine)!*~query valueit's%20(fine)!*~
it's (fine)!*~form datait%27s+%28fine%29%21*%7E
你好query value%E4%BD%A0%E5%A5%BD
😀query value%F0%9F%98%80

Decoding 100%zz fails at character 4, the % that is not followed by hex digits; with Keep invalid % as it is turned on, a lone trailing % as in 100% is kept as text. Decoding %E4%BD fails because it is the first two bytes of a three-byte character. Decoding %25E4%25BD%25A0 once gives %E4%BD%A0, and decoding that again gives 你 — the telltale sign of a value that was encoded twice.

Pasting https://user@例子.com:8443/路径/a%20b?q=%E4%BD%A0&q=2&empty=&flag#frag lists the host as 例子.com (xn--fsqu00a.com), port 8443, path /路径/a b and four parameters: q = 你, q = 2, empty = (empty) and flag = (empty). Repeated keys and empty values are kept, because servers treat them differently.

Common mistakes

  • Encoding twice. A value that is encoded and then placed in a URL that is encoded again shows up as %2520 instead of %20. Encode each value once, when you insert it.
  • Encoding a whole URL as a component. encodeURIComponent turns https:// into https%3A%2F%2F. That is correct when the URL is itself a parameter value (a redirect target, for example), and wrong otherwise.
  • Treating + as a space everywhere. Only form data uses + for spaces. In a path, + is a literal plus sign.

Limits

  • UTF-8 only. Old sites sometimes encoded text in GBK or Windows-1252. Those bytes are not valid UTF-8 and are reported as errors; with the lenient option they are kept as escapes.
  • One layer at a time. Decoding removes one level of encoding. Use Use result as input to decode again when a value was encoded twice.
  • The parts panel follows the WHATWG URL parser, the same one browsers use. A text without a scheme is treated as https:// for display, and a text with spaces is not considered a URL.

Frequently asked questions

What is the difference between encodeURI and encodeURIComponent?

encodeURIComponent encodes the characters that have a meaning in URLs, such as / ? & =, so it is right for a single value. encodeURI leaves them alone and is only for a complete URL.

Should a space be %20 or +?

In a path and in most APIs, %20. In HTML form data and many search URLs, +. Both decode to a space when the receiver expects form encoding.

Why does my URL contain %2520?

It was encoded twice: % itself became %25. Decode it twice, and fix the code so it encodes only once.

Why do Chinese characters become so long?

Each Chinese character is three bytes in UTF-8, and each byte becomes three characters (%XX), so one character turns into nine.

Is my text sent anywhere?

No. Encoding, decoding and URL parsing all happen in your browser.

Sources and further reading

↵ to open · Esc to close