Free tool

URL decode and encode

URL decoding turns %XX escapes back into characters: %20 is a space, %3D is =, %C3%A9 is é. Paste encoded text to decode it or plain text to encode it. You see all four common encodings side by side, and double-encoded or broken input is pointed out instead of failing.

Free · no sign-up · runs in your browser, nothing is uploaded

Encoded input
Decoded

Decoded text appears here as you type.

How URL encoding works

A URL may only contain a small set of ASCII characters, and some of them have a job: / separates path segments, ? starts the query, & and = split parameters, # starts the fragment. Any other character, or one of those used as plain data, is written as a percent sign and two hex digits: the byte value. This is called percent-encoding (RFC 3986, section 2.1).

Characters outside ASCII are first turned into UTF-8 bytes, and each byte is escaped. é is the two bytes C3 A9, so it becomes %C3%A9; the emoji 👋 is four bytes and becomes %F0%9F%91%8B. Decoding does the reverse: it collects the bytes and reads them as UTF-8. The table under the tool shows these bytes for every character that changes.

CharacterEncodedWhy it is escaped
space%20 or +Not allowed in a URL; + only in query strings
&%26Separates query parameters
=%3DSeparates a key from its value
?%3FStarts the query
/%2FSeparates path segments
#%23Starts the fragment
%%25Starts an escape
+%2BMeans a space in form data
'%27Escaped by RFC 3986 strict encoders, not by encodeURIComponent
é%C3%A9Not ASCII: its two UTF-8 bytes

encodeURIComponent vs encodeURI vs form encoding

"URL encode" means slightly different things in different places. The tool shows all four results for the same text, so you can pick the one the receiving side expects.

EncodingLeaves as isSpaceUse it for
encodeURIComponent()A-Z a-z 0-9 - _ . ! ~ * ' ( )%20One query value or path segment
encodeURI()The above plus ; / ? : @ & = + $ , #%20A whole URL that is already structured
URLSearchParamsA-Z a-z 0-9 * - . _+HTML form bodies and query strings
RFC 3986 strictA-Z a-z 0-9 - . _ ~%20OAuth signatures, AWS SigV4, PHP rawurlencode()

The common bug is running encodeURI() on a value: a&b=c stays as it is and the server sees an extra parameter. Encode values with encodeURIComponent(), or build the query with URLSearchParams and let it do the escaping. To edit the parameters of a URL you already have, use the URL parser.

URL decode and encode in code

JavaScript

encodeURIComponent('café & crème');   // 'caf%C3%A9%20%26%20cr%C3%A8me'
decodeURIComponent('caf%C3%A9%20%26');  // 'café &'

// Form style (+ for space): let URLSearchParams do it
new URLSearchParams({ q: 'red shoes' }).toString(); // 'q=red+shoes'
new URLSearchParams('q=red+shoes').get('q');        // 'red shoes'

// decodeURIComponent does not turn + into a space
decodeURIComponent('red+shoes'.replace(/\+/g, ' '));

Python

from urllib.parse import quote, quote_plus, unquote, unquote_plus

quote('café & crème', safe='')   # 'caf%C3%A9%20%26%20cr%C3%A8me'
quote_plus('red shoes')          # 'red+shoes'
unquote('caf%C3%A9')             # 'café'
unquote_plus('red+shoes')        # 'red shoes'

Note that quote() leaves / alone by default (safe='/'); pass safe='' to encode a single value.

PHP

rawurlencode('café & crème');  // 'caf%C3%A9%20%26%20cr%C3%A8me' (RFC 3986)
urlencode('red shoes');         // 'red+shoes' (form style)
rawurldecode('a%20b');          // 'a b'
urldecode('a+b');               // 'a b'

Go

url.QueryEscape("red shoes & co")   // "red+shoes+%26+co"
url.PathEscape("red shoes")         // "red%20shoes"
s, err := url.QueryUnescape("a%20b+c") // "a b c", err on bad escapes

Java

URLEncoder.encode("red shoes", StandardCharsets.UTF_8); // "red+shoes"
URLDecoder.decode("a%20b+c", StandardCharsets.UTF_8);   // "a b c"

Java's URLEncoder writes form encoding (spaces as +), so it is not the right tool for path segments.

Common URL decoding problems

Double encoding. Text that went through an encoder twice has %25 before other escapes: %2520 instead of %20. It usually comes from encoding a value that was already encoded, often a redirect URL passed inside another URL. RFC 3986 says not to encode or decode the same string more than once for this reason. The tool detects it and can decode until nothing is left.

A literal % sign. 50% off is not valid encoded text: a % must start an escape. decodeURIComponent() throws on it; this tool keeps it and shows where it is. Encoded, it is 50%25%20off.

Mojibake like é or �. If é shows up as é, UTF-8 bytes were read as Latin-1 somewhere. If you see �, Latin-1 bytes (like %E9) were read as UTF-8: switch the charset to Latin-1.

Plus signs. A + in a query string usually means a space, but a phone number like +15551234 or a Base64 value sent without encoding loses its plus. Encode a real plus as %2B. Turn "+ means space" off when the input is not form data.

Other text formats have their own escaping: see the string escape tool for JSON, HTML and SQL, and the Base64 decoder for Base64URL values. For API clients and testing tools, browse API tools on DevHunt.

FAQ

How do I decode a URL?+

Paste it into the box above and the decoded text shows up as you type. Every %XX escape is turned back into its byte, and the bytes are read as UTF-8. In code, use decodeURIComponent() in JavaScript, urllib.parse.unquote() in Python, rawurldecode() in PHP and url.QueryUnescape() or url.PathUnescape() in Go.

What is %20 in a URL?+

%20 is a space. The 20 is the hexadecimal code of the space character (32 in decimal). In a query string a space can also be written as +, because HTML forms send it that way, so q=red%20shoes and q=red+shoes mean the same thing to most servers.

What do %27, %3D and %3F mean in a URL?+

%27 is an apostrophe ('), %3D is an equals sign (=) and %3F is a question mark (?). = and ? have a job in a URL (they separate keys from values and the path from the query), so they are escaped when they are part of a value. Other common ones: %26 is &, %2F is /, %23 is #, %25 is % and %2B is +.

What is the difference between encodeURI and encodeURIComponent?+

encodeURI() is for a whole URL: it leaves the characters that give a URL its structure (: / ? # & = + $ , ; @) alone. encodeURIComponent() is for one piece, like a single query value: it escapes those characters too, so a value containing & or = cannot break the URL. When you build a URL from user input, encode each value with encodeURIComponent().

Why does decodeURIComponent throw "URI malformed"?+

It throws a URIError when a % is not followed by two hex digits (like "100%" or "%G1") or when the bytes are not valid UTF-8 (like %E9 from Latin-1 text). This tool never throws: it leaves the bad escape as it is, tells you its line and column, and offers a Latin-1 charset for old Latin-1 encoded text.

What does double URL encoding look like?+

A value that was encoded twice has %25 in front of other escapes: a space becomes %2520 instead of %20, because the % of %20 was encoded again as %25. Decoding once leaves %20 behind. Turn on "Decode until no %XX is left" and the tool keeps decoding and tells you how many rounds it took.

Should a space be + or %20?+

In the path, always %20: a + in a path is a literal plus sign. In a query string both work with most servers, because the application/x-www-form-urlencoded format that HTML forms use writes spaces as +. If you are unsure, %20 is the safer choice; it means a space everywhere.

Is URL encoding the same as encryption?+

No. URL encoding only replaces characters that are not allowed or that have a special meaning in a URL. Anyone can decode it, so it does not hide anything. Everything on this page runs in your browser and nothing you paste is sent anywhere.

Sources: RFC 3986 (URI syntax, percent-encoding) · WHATWG URL Standard (form-urlencoded) · MDN: encodeURIComponent() · MDN: encodeURI() · MDN: decodeURIComponent() · Python urllib.parse · PHP rawurlencode() · Go net/url · Java URLEncoder. Checked 2026-10-30.