URL Encode & Decode

URL encoding (percent-encoding) replaces characters that are not allowed in a URL with a % and two hex digits, so a space becomes %20 and é becomes %C3%A9. Paste text to encode it for a query string or path, or paste an encoded string to decode it.

Output

Which characters get encoded

A URL may only contain a limited set of ASCII characters. Everything else, including spaces, non-English letters and emoji, is first turned into UTF-8 bytes, and each byte is written as % plus two hexadecimal digits. Characters that have a job in a URL, such as ?, &, =, / and #, must also be encoded when they appear inside a value.

CharacterEncodedWhy
space%20 (or + in forms)Not allowed in URLs
&%26Separates query parameters
=%3DSeparates name and value
?%3FStarts the query string
#%23Starts the fragment
/%2FSeparates path segments
%%25Starts an escape
é%C3%A9Two UTF-8 bytes

In code

encodeURIComponent('café & croissants'); // caf%C3%A9%20%26%20croissants
decodeURIComponent('caf%C3%A9');         // café

// Building a query string safely
new URLSearchParams({ q: 'café & croissants' }).toString(); // q=caf%C3%A9+%26+croissants

Frequently asked questions

What is the difference between encodeURI and encodeURIComponent?

encodeURIComponent encodes everything except letters, digits and - _ . ! ~ * ' ( ), so it is the one to use for a single query parameter value or path segment. encodeURI leaves characters with meaning in a full URL, such as : / ? # & =, untouched, so it is only for encoding a whole URL that is already structured correctly.

Should a space be %20 or +?

In a URL path, a space must be %20. In a query string sent as application/x-www-form-urlencoded (what HTML forms and URLSearchParams produce), a space becomes +. Both decode back to a space in a query string, but + in a path is a literal plus sign.

Why do I get "URI malformed" when decoding?

decodeURIComponent throws when it finds a % that is not followed by two hex digits, or a sequence of bytes that is not valid UTF-8. A common cause is a literal % sign that was never encoded, such as "50% off". It should be sent as %25.

Related tools