URL Decoder

Paste a URL or component, get the readable text back. Component mode for query values, full-URL mode for whole URLs — handles UTF-8 percent-escapes correctly.

Why decode URL escapes?

How it works

Component mode runs decodeURIComponent — turns every %HH back into a byte, then UTF-8 decodes the bytes into text. Use this for a single query value or path segment that was encoded with encodeURIComponent. Full-URL mode uses decodeURI which leaves :/?#&= alone — for re-displaying a whole URL with the structural punctuation intact. Both refuse malformed input (e.g. an unfinished %2 with no second hex digit) with a clear error.

Frequently asked questions

Why am I getting a malformed-input error?

Most often a stray % that wasn't part of an escape (e.g. someone typed 100% in a comment) or an incomplete escape (%2 with no second hex digit). Those are syntactically invalid percent-encoding and the decoder refuses rather than guess.

Component vs full-URL — which is safer to default to?

Component. It decodes more aggressively (every % escape including / : ?), so you see the full original content. Full-URL preserves URL structure, useful only when you want to re-display the whole URL afterward.

Will it decode + as space?

No, that's a form-encoding convention (application/x-www-form-urlencoded) where + replaces space inside POST bodies. URL path/query encoding uses %20 for space and leaves + alone. If you see + meant as space, replace + with %20 first, then decode.

How does it handle UTF-8?

Multi-byte characters appear as multiple consecutive percent-escapes (e.g. %E6%97%A5 is 日 in UTF-8). The decoder consumes the byte sequence and reconstructs the original character. Mismatched byte sequences produce replacement characters but don't error out — by design.

Is my input logged?

No. The decoder is a one-line JavaScript call on this page. Pasted URLs (including any tokens or PII inside them) stay on your device.

About this tool

URL decoding is the inverse of percent-encoding: each %HH consumes two hex digits and emits the corresponding byte; sequences of bytes are then UTF-8 decoded back to text. The work is mechanical, but the choice of decoder matters. decodeURIComponent unwraps everything; decodeURI only unwraps percent-escapes that don't change URL structure. Use the wrong one and you either get a still-encoded result (full-URL on a single component) or a URL whose structure has dissolved (component on a whole URL). The form-encoding + ↔ space convention is a separate, older standard — modern URL encoding leaves + literal.