Skip to content
Kalio
Developer

URL encoder and decoder

Percent-encode and decode URLs and query parameters, with a breakdown of any URL into its origin, path and decoded parameters.

Use this for a single query value - reserved characters are escaped.

Ready · runs on your device

Nothing is uploaded. This tool runs entirely inside your browser tab. Your files and figures stay on your device - we never receive them, so we cannot read, store or lose them.

What percent encoding does

URLs may only contain a restricted set of ASCII characters. Anything else - spaces, most punctuation, every non-Latin script, emoji - has to be represented as % followed by the two-digit hex value of each UTF-8 byte.

space  → %20
&      → %26
=      → %3D
/      → %2F
?      → %3F
#      → %23
+      → %2B
é      → %C3%A9   (two bytes in UTF-8)
日     → %E6%97%A5 (three bytes)

Characters that never need encoding are the unreserved set: A–Z, a–z, 0–9, and - . _ ~.

Choosing the right mode

This is the whole game, and getting it wrong is the source of most URL bugs.

Component mode - for a single value going into a query parameter or path segment. It escapes & = ? / # + along with everything else, so a value containing an ampersand cannot be mistaken for a parameter separator.

Full-URL mode - for an entire URL you want to remain functional. It leaves : / ? # & = alone so the structure survives, and escapes only spaces and other genuinely illegal characters.

Consider a search for coffee & tea:

Correct:
  /search?q=coffee%20%26%20tea

Wrong (full-URL mode on the value):
  /search?q=coffee & tea
  → the & starts a new parameter; you get q=coffee and an empty "tea"

Wrong (component mode on the whole URL):
  %2Fsearch%3Fq%3Dcoffee%20%26%20tea
  → no longer a URL at all

Double encoding

A URL that is encoded twice produces %2520 where %20 was intended, because the % itself gets escaped to %25. Seeing %25 in a URL that should not contain a literal percent sign is the signature of this bug.

It typically happens when a value is encoded by application code and then encoded again by a framework or an HTTP client. Encode exactly once, at the point where the value is placed into the URL.

The URL breakdown

When your input parses as a URL, the tool splits it into origin, path, fragment and decoded query parameters. This is usually faster than decoding by hand when you are debugging an OAuth redirect, a tracking link with a dozen UTM parameters, or an API call that returns the wrong result.

Note that the fragment - everything after # - is never sent to the server. It is handled entirely by the browser, which is why single-page applications historically used it for routing and why it is a poor place to put anything the backend needs.

Reserved characters and what they mean

CharacterRole
?Starts the query string
&Separates parameters
=Separates a key from its value
#Starts the fragment; never sent to the server
/Separates path segments
:Separates the scheme, and the host from the port
@Separates credentials from the host
+A space, but only inside a form-encoded query string

Common questions

What is the difference between the two modes?

Component mode (encodeURIComponent) also escapes the structural characters that separate parts of a URL, which is what you need for a single parameter value. Full-URL mode (encodeURI) leaves them intact so the URL keeps working. Using the wrong one is the most common URL bug there is - component mode on a whole URL breaks it, full-URL mode on a value lets that value break out of its parameter.

Why is a space sometimes %20 and sometimes +?

Both appear. %20 is correct percent-encoding and works anywhere in a URL. The + convention comes from HTML form submission (application/x-www-form-urlencoded) and is only valid in a query string. In a path, + means a literal plus sign. Use %20 unless you are specifically producing form-encoded data.

Do I need to encode non-English characters?

For transmission, yes - they are converted to UTF-8 bytes and percent-encoded, so 日 becomes %E6%97%A5. Modern browsers display the readable form in the address bar and encode on the wire, so you will often see both representations of the same URL.

Why does decoding sometimes fail?

A lone % that is not followed by two valid hexadecimal digits is malformed. It usually means the string was double-encoded, then partially decoded, or that a literal percent sign was never escaped as %25.

Last reviewed