Overview
Decodes percent-encoded strings — %20, %C3%A9 and friends — back into readable text, and percent-encodes in the other direction. Handles the two conventions that coexist on the web: strict RFC-style decoding where + is a literal plus, and the HTML form convention where + means a space, switchable with one checkbox. Malformed input produces a clear error instead of silent garbage.
How It Works
Choose Encode or Decode at the top of the panel; the tool pre-selects Decode when you arrive at this page. Paste into the left box and the result appears live on the right. In decode mode a checkbox appears: Treat + as space (form-urlencoded). Leave it off for strict percent-decoding, where a plus stays a plus; switch it on when the input is a query string or form body built by the application/x-www-form-urlencoded convention. Invalid escapes do not fail silently — the output shows an explicit error naming the cause.
Step-by-Step Usage Guide
- Paste the encoded string into the input box; decode mode is pre-selected.
- If the input comes from an HTML form or a query string with + characters, tick Treat + as space.
- Read the output; an explicit error means the input was malformed — look for a lone % or a truncated escape.
- If the result still contains % sequences, it was encoded twice; run the decode again.
Technical Specifications & Standards
Percent-encoding is a byte-level convention: characters that are illegal or ambiguous in a URL component are replaced by % followed by the two-digit hexadecimal value of each UTF-8 byte. É is two bytes (0xC3 0xA9), so it becomes %C3%A9 — verified here — and a space becomes %20, never +, in this convention. The encode side uses encodeURIComponent, which leaves unreserved characters (A–Z, a–z, 0–9, hyphen, underscore, period) plus a small allowed set — !, ', (, ), ~ and * — bare and escapes everything else; it encodes space as %20, so an encoded value round-trips byte-exactly. Decoding is where tools betray their users, in three distinct ways. First, strictness: decodeURIComponent throws a URIError on malformed input — a trailing lone percent in 100%, a truncated %2, or % followed by non-hexadecimal %zz all throw, and this tool surfaces that as an error message rather than passing the damage through, because a failed decode almost always means the string was double-encoded or truncated upstream. Second, the plus: RFC-style percent-encoding treats + as a reserved, literal plus sign, but the HTML form convention — what a browser does when it submits a form and what URLSearchParams implements — encodes a space as +. Feeding form output to a strict decoder leaves the plus signs in: verified, a+b decodes to a+b strictly and to a b with the form convention. The checkbox exists because both behaviours are correct in their own context and wrong in the other's. Third, layering: encoding twice is a classic bug — a space encoded to %20 and then encoded again becomes %2520, because the percent itself is a character that must be encoded. Strict decoding of %2520 yields %20, revealing the extra layer; if your decoded output still contains percent escapes, decode again.
Targeted Use Cases
- Reading the q= parameter of a URL someone pasted into a bug report.
- Decoding log lines and webhook payloads where values arrive percent-encoded.
- Debugging double-encoded links — the %25 signature — before fixing the encoder that produced them.
- Checking whether a + in a query value means a space (form convention) or a literal plus (strict convention).
Notes & Gotchas
- Decode exactly once per encoding layer; if output still shows %XX sequences, there was another layer.
- Never guess the plus convention from the data — decide by source: form bodies and query strings use + for space; path segments use %20.
- Treat a URIError as information: a lone % or truncated escape means the string was cut or corrupted before it reached you.
- For values you will re-encode, decode first, edit the plain text, then encode once — editing encoded text is how double-encoding starts.
Frequently Asked Questions
Why does my + stay a + after decoding?
Strict percent-decoding treats + as a literal plus character — that is the RFC convention, and it is the default here. If your input came from an HTML form or a query string built by URLSearchParams, tick the Treat + as space checkbox and the plus signs become spaces.
What does “Error: Invalid or malformed URL encoding string.” mean?
decodeURIComponent threw a URIError because the input contains an escape it cannot parse: a lone trailing percent, a truncated two-digit escape such as %2, or non-hexadecimal characters after a percent. The string is damaged or truncated upstream; fixing the decoder cannot recover it.
How is this different from decodeURI?
decodeURI decodes only characters that are illegal in a full URL and deliberately leaves reserved separators such as / and %2F's slash encoded — %2F stays %2F — while decodeURIComponent decodes every percent escape. Use the component function for parameter values, which is what this tool does.
Why does %2520 decode to %20 instead of a space?
Because it was encoded twice. The space became %20, then the percent of %20 was itself encoded to %25, producing %2520. One decode removes one layer; decode again to reach the space, then fix the code that encoded twice.