URL decode and encode

Paste a percent-encoded link to read it, or type text to make it safe for a URL. It converts as you type, handles UTF-8 properly, and when a % sequence is broken it shows you exactly where.

Direction
Every %XX is turned back into its character, read as UTF-8. Paste a whole link, a query string or a single value.
Options

Paste an encoded URL or text into the box to decode it.

Encoded URLs turn up in server logs, redirects and API calls. Need a server for your own site or API? From €3.02 a month today, among 2,226 servers.

Split a URL into its parts

Scheme
https
Host
shop.example.com
Port
8443
Path
/search/r%C3%A9sum%C3%A9
Path, decoded
/search/résumé
Query string
?q=vps+hosting&sort=price&tag=ssd&tag=nvme&city=M%C3%BCnchen
Fragment
#results
Origin
https://shop.example.com:8443

Query parameters: 5

  1. q vps hosting
  2. sort price
  3. tag ssd
  4. tag nvme
  5. city München

Names and values are decoded, with + read as a space, the way a server reads them. A name can appear more than once.

Works in your browser: nothing you type is sent anywhere.

How URL encoding works

A URL may only contain a small set of ASCII characters, and some of them have a job: / separates the path, ? starts the query, & and = split it into parameters, # starts the fragment. Any other character, or one of these used as plain data, is written as % and two hex digits for each of its bytes in UTF-8. This is called percent-encoding (RFC 3986).

space  →  %20          (or + in form data)
&      →  %26
/      →  %2F
é      →  C3 A9  →  %C3%A9
€      →  E2 82 AC  →  %E2%82%AC

Which characters to encode depends on what you are encoding. A single value, such as a search term, must have / ? & = # encoded too, or it would break the URL it goes into: that is encodeURIComponent in JavaScript and urlencode in PHP. A whole URL must keep them, or it stops being a link: that is encodeURI. HTML forms send spaces as + instead of %20 (application/x-www-form-urlencoded), so a + in a query string usually means a space.

Decoding reverses it: every %XX becomes a byte, and the bytes are read as UTF-8. The browser's own decodeURIComponent only says “URI malformed” when something is wrong. This page names the sequence and points at it: a % without two hex digits after it, or bytes that are not valid UTF-8, which usually means the text was encoded as Latin-1.

Example

The search term “vps hosting/€5” as one value becomes vps%20hosting%2F%E2%82%AC5: the space is %20, the slash %2F, and the euro sign, three bytes in UTF-8, becomes %E2%82%AC. With “Write spaces as +” for form data it becomes vps+hosting%2F%E2%82%AC5. Decoding r%C3%A9sum%C3%A9 gives résumé, and decoding caf%E9 fails at %E9, because that is é in Latin-1, not in UTF-8.

Questions

What is URL encoding?

URL encoding, or percent-encoding, writes characters that are not allowed in a URL, or that have a special meaning there, as % followed by two hex digits for each byte. A space becomes %20, & becomes %26 and é becomes %C3%A9. It lets any text travel safely inside a link or a query string.

What is the difference between encodeURI and encodeURIComponent?

encodeURI is for a whole address: it keeps characters with a job in a URL, such as : / ? # & =, so the link still works. encodeURIComponent is for one piece that goes inside a URL, such as a query value: it encodes those characters too, so a & in the value cannot start a new parameter. When in doubt, encode each value with encodeURIComponent and then join them.

Should a space be %20 or +?

Both are correct in different places. In the path of a URL, a space must be %20. In a query string sent by an HTML form (application/x-www-form-urlencoded), a space is written as +, and a real plus sign as %2B. Most servers read both in a query string. When decoding form data, turn on “Read + as a space”.

Why do I get “URI malformed” when decoding?

Either a % is not followed by two hex digits, for example a plain “100%” or “%G1”, or the %XX bytes are not valid UTF-8, often because the text was encoded in Latin-1 (é as %E9) or a multi-byte character was cut off. This page shows which sequence is wrong and where it is, so you can fix it.

How do I URL-decode on the command line or in code?

In JavaScript: decodeURIComponent(s), after s.replace(/\+/g, ' ') for form data. In Python: urllib.parse.unquote(s), or unquote_plus(s) for form data. In PHP: rawurldecode($s), or urldecode($s), which also turns + into a space. In a shell with Python installed: python3 -c "import sys, urllib.parse as u; print(u.unquote(sys.argv[1]))" 'r%C3%A9sum%C3%A9'.