toooly-box

URL Decoder

Paste an encoded URL and read what it actually says: with the parameters listed separately.

runs locally
URL encoding
For one value inside a query string: & = ? / # and spaces are all escaped.
Percent-encoded
Decoded text

What does %20 mean in a URL?

%20 is a space. In a URL every byte can be written as a percent sign followed by its two-digit hex value, and 20 in hexadecimal is 32, the character code for a space. A URL decoder turns those sequences back into the characters they stand for.

How it works

Decoding reverses percent-encoding: every %XX is read back as the byte XX, and the resulting bytes are read as UTF-8. %C3%A8 comes back as è, %20 as a space.

A URL with a query string is also split into its parameters and shown as a table, because the question people usually have is not "what does this line say" but "what is in utm_content".

Whether + means a space depends on where the string came from: in a form body it does, everywhere else it is a literal plus. That is a mode here rather than a guess, because guessing corrupts base64 values.

What a URL decoder does

An encoded URL is unreadable on purpose: the characters that would confuse a parser have been replaced by % escapes, and anything outside ASCII has been turned into its UTF-8 bytes. A decoder undoes both steps, so https%3A%2F%2Fexample.com%2Fcaff%C3%A8 becomes https://example.com/caffè and you can see what was actually being linked to.

That matters most when the URL is carrying another URL. Redirect parameters, OAuth callbacks, tracking wrappers and consent flows all nest one address inside another, sometimes twice, and the only way to know where a link really goes is to decode it. Doing that in a page that runs on your own machine is better than pasting a signed callback into a stranger’s server.

How to use it

  • Paste the whole URL or just the part you care about. Both work: the decoder does not require a valid URL, only a string.
  • Read the parameter table when there is a query string, each parameter is listed with its value already decoded. This is usually the answer you came for.
  • Pick the mode form mode reads + as a space, which is right for a submitted form body and wrong for everything else.
  • Decode twice when needed if the result still contains %XX sequences, it was double-encoded. Send it back up and decode again.
  • Send back moves the result into the input, which is how you peel a nested URL one layer at a time.

The hard cases

A malformed escape stops the whole decode, and that is correct rather than unhelpful. %zz is not a byte, and a decoder that skipped it would hand you a string that silently differs from the original. The tool names the sequence that broke instead, which is usually enough to spot the truncated copy-paste behind it.

A bare % is the most common version of that. "100% off" pasted into a URL field is not valid encoding: the parser reads % o as an escape, finds no hex digits, and gives up. The fix is to encode the value first: a literal percent sign is %25.

And a decoded string is not a safe string. Decoding turns %3Cscript%3E back into a script tag; it undoes an encoding, it does not sanitise anything. Whatever you do with the result afterwards needs its own escaping for wherever it is going.

When the output looks wrong

  • The result still has %20 in it the input was encoded twice. Decode again; each pass removes one layer.
  • Accents come out as mojibake the escapes are Latin-1 bytes, not UTF-8. An old system somewhere encoded è as %E8 rather than %C3%A8, and there is no way to read that as UTF-8.
  • Plus signs became spaces you are in form mode on a string that is not a form body. Switch modes: this matters for base64 values, which contain + legitimately.
  • An error about an incomplete escape a % that is not followed by two hex digits, usually a literal percent sign that was never encoded, or a URL that got cut when it was copied.
  • A parameter is missing check whether it is after the #. The fragment is not part of the query string and never reaches the server.

What the parts of a URL are called

  • Query string everything after the ?, as name=value pairs joined by &. Its order is not meaningful and duplicate names are allowed, which is why servers disagree about what ?a=1&a=2 means.
  • Fragment everything after the #. It stays in the browser: it is never sent to the server, so it never appears in a server log.
  • Path segment the parts between slashes. A / inside a value has to be encoded, or it becomes a new segment.
  • Percent escape the % plus two hex digits. Case-insensitive, so %C3%A8 and %c3%a8 decode identically.
  • UTM parameters utm_source, utm_medium, utm_campaign and friends: ordinary query parameters that analytics tools agree to read. Nothing about them is special to the URL itself.

Questions people ask

How do I decode a URL?

Paste it in. Every %XX is read back as a byte and the bytes are read as UTF-8, so %C3%A8 becomes è and %20 becomes a space.

Why does my decoded text still contain %20?

It was encoded twice. Each decode removes one layer, so send the result back up and decode again.

Does + mean a space?

Only in a form body. Everywhere else + is a literal plus sign, which is why decoding it as a space would corrupt base64 values.

What does an "incomplete escape" error mean?

A % that is not followed by two hex digits. Usually a literal percent sign that was never encoded, or a URL truncated when it was copied.

Is a decoded URL safe to use?

Decoding is not sanitising. It will happily give you back a script tag; whatever you do with the result needs its own escaping for its destination.