About this tool
This URL decoder and encoder converts text to and from percent-encoding, the %20-style escapes used in web addresses. It offers the three encodings you meet in practice: encodeURIComponent for a single value, encodeURI for a whole URL, and form encoding, where a space is +. Decoding reports the exact position of a broken % sequence and warns when a string looks encoded twice. Everything runs in your browser.
How to use the URL encoder and decoder
- Paste the text. For URL decode, paste the encoded string or the whole address.
- Choose the mode. Use Component for a value you will put inside a URL, Full URL for a complete address, and Form data for HTML form bodies or query strings built the way forms build them.
- Click Encode or Decode. If the decoded result still contains escapes such as
%20, click Decode again.
How URL encoding works
URL encoding, properly called percent-encoding, is defined in RFC 3986, section 2. Each character that may not appear as itself is converted to UTF-8 bytes, and each byte is written as % followed by two hexadecimal digits. RFC 3986 says uppercase and lowercase hex digits are equivalent but recommends uppercase, which is what this tool and the browser functions produce. Decoding reverses the steps: every %XX becomes a byte, and the bytes are read as UTF-8.
Reserved and unreserved characters
RFC 3986 splits characters into two groups. Unreserved characters, the letters A–Z and a–z, the digits 0–9 and - . _ ~, never need encoding. Reserved characters act as delimiters: the general delimiters : / ? # [ ] @ and the sub-delimiters ! $ & ' ( ) * + , ; =. A reserved character must be encoded when it is data rather than structure. In ?q=tom&jerry the & would end the value early, so a value containing it must carry %26 instead. Everything else, including spaces, quotes and all non-ASCII characters, is always encoded.
Which mode to use
- Component for any piece you insert into a URL: a search term, a redirect target inside
?next=, a file name in a path. It encodes every reserved character except! ' ( ) *. - Full URL only for a complete address that has spaces or non-ASCII letters in it. It leaves the reserved characters other than
[and]alone, so it cannot protect an&or=inside a value. Decoding in this mode also keeps escapes of reserved characters, such as%26, as they are, just asdecodeURIdoes. - Form data for
application/x-www-form-urlencodedbodies and for query strings made withURLSearchParams. The WHATWG URL Standard defines it: only letters, digits and* - . _stay as they are, a space becomes+, and everything else is percent-encoded.
Worked example
The sample text in the box, café & tea = 50% off!, encodes three ways:
| Mode | Result |
|---|---|
| Component | caf%C3%A9%20%26%20tea%20%3D%2050%25%20off! |
| Full URL | caf%C3%A9%20&%20tea%20=%2050%25%20off! |
| Form data | caf%C3%A9+%26+tea+%3D+50%25+off%21 |
The é becomes the two UTF-8 bytes %C3%A9 in every mode, and the % itself becomes %25. Only Component and Form data protect the & and =, so only those results are safe as a query value. Form data also encodes the !.
URL encoding chart
These codes were computed in Python and checked against encodeURIComponent, encodeURI and URLSearchParams in Node.js.
| Character | Component | Full URL | Form data |
|---|---|---|---|
| space | %20 | %20 | + |
" | %22 | %22 | %22 |
# | %23 | unchanged | %23 |
$ | %24 | unchanged | %24 |
% | %25 | %25 | %25 |
& | %26 | unchanged | %26 |
' | unchanged | unchanged | %27 |
( | unchanged | unchanged | %28 |
) | unchanged | unchanged | %29 |
* | unchanged | unchanged | unchanged |
+ | %2B | unchanged | %2B |
, | %2C | unchanged | %2C |
/ | %2F | unchanged | %2F |
: | %3A | unchanged | %3A |
; | %3B | unchanged | %3B |
= | %3D | unchanged | %3D |
? | %3F | unchanged | %3F |
@ | %40 | unchanged | %40 |
[ | %5B | %5B | %5B |
] | %5D | %5D | %5D |
~ | unchanged | unchanged | %7E |
! | unchanged | unchanged | %21 |
é | %C3%A9 | %C3%A9 | %C3%A9 |
€ | %E2%82%AC | %E2%82%AC | %E2%82%AC |
😀 (emoji) | %F0%9F%98%80 | %F0%9F%98%80 | %F0%9F%98%80 |
Spaces: %20 or +?
Both are correct in their own place. In a path, %20 is the only correct form; a + in a path is a literal plus sign. In a query string, servers that parse it as form data turn + into a space, which is why a plus sign that is meant literally must be sent as %2B. The UTM Builder builds its query with URLSearchParams, so a space in a campaign name comes out as +. When in doubt, %20 works in both places.
Non-ASCII characters
Characters outside ASCII are encoded as their UTF-8 bytes, which RFC 3986 section 2.5 recommends. é is 2 bytes (%C3%A9), € is 3 (%E2%82%AC), each character of 日本 is 3 (%E6%97%A5%E6%9C%AC) and an emoji such as 😀 is 4 (%F0%9F%98%80). Domain names are different: international domain names are converted to Punycode, a form starting with xn--, not percent-encoded.
Decoding errors and double encoding
- A broken
%sequence. Every%must be followed by two hex digits.50% offpasted unencoded fails, and the error shows where. Encode the text instead if it was never encoded. - Bytes that are not UTF-8. Older systems wrote
éas the single Latin-1 byte%E9. On its own that is not valid UTF-8, so the decoder names the sequence rather than guessing. - Double encoding.
%2520is a%20whose%was encoded again. RFC 3986 warns that a string must not be encoded or decoded more than once. This tool flags input that already contains escapes before you encode it, and offers Decode again when a result still contains them.
Percent-encoding keeps text readable and only escapes what it must. To pack arbitrary binary data into text instead, use the Base64 encoder.
Frequently asked questions
URL encoding, or percent-encoding, replaces characters that cannot appear as themselves in a URL with a % sign and two hexadecimal digits for each UTF-8 byte. A space becomes %20, an ampersand %26 and é becomes %C3%A9. URL decoding turns those escapes back into the original text.
encodeURI is for a complete address and leaves characters with structural meaning, such as : / ? # & and =, untouched. encodeURIComponent also encodes those, so it is the right choice for a single value placed inside a query string or path segment. Use Component mode for values and Full URL mode for whole addresses.
Use %20 in a path and whenever you are unsure. The + form belongs to application/x-www-form-urlencoded data, which HTML forms and URLSearchParams produce, and servers decode + as a space only in query strings and form bodies. Choose Form data mode to encode or decode that format.
Every % must be followed by two hexadecimal digits, and the bytes must form valid UTF-8. The error message shows the position of the problem. A literal percent sign, as in 50% off, means the text was never encoded. A lone byte such as %E9 is old Latin-1 encoding rather than UTF-8.
It is a space that has been encoded twice. The first pass turned the space into %20, and a second pass encoded the percent sign as %25, giving %2520. Decode it once to get %20, then click Decode again to get the space, and fix the code that encodes the value twice.
encodeURIComponent and encodeURI leave the apostrophe, along with ! * ( ) and ~, unencoded. RFC 3986 lists ' ! * ( ) as reserved sub-delimiters, so a strict system may want them escaped. Form data mode encodes the apostrophe as %27, or you can replace it by hand after encoding.
They are converted to UTF-8 bytes first, and each byte is percent-encoded. é takes 2 bytes (%C3%A9), the euro sign and most Chinese and Japanese characters take 3, and most emoji take 4, so a single emoji becomes 12 characters such as %F0%9F%98%80.