Paste a percent-encoded string and get the original text back. urldecode runs locally in your browser — nothing is uploaded, nothing is stored.
urldecode reverses percent-encoding. When a browser, a form, or an API puts a URL on the wire, reserved characters and anything outside plain ASCII get rewritten as a percent sign followed by two hex digits. urldecode reads each %XX sequence, converts the hex back into a byte, and reassembles those bytes into text using the correct character set.
A concrete case: the search phrase café au lait travels through a query string as caf%C3%A9%20au%20lait. Run urldecode on it and you get café au lait back. The %20 is an ASCII space; %C3%A9 is two UTF-8 bytes that together spell é. Hand those same bytes to urldecode with the wrong charset and you get mojibake instead of letters. That is why urldecode almost always travels together with a charset setting.
%20 → space%2F → /%3F → ?%26 → &%3D → =%23 → #%25 → the % sign itselfThat last row bites people. A literal % in the source text is stored as %25, which is why nested values keep shrinking every time you run urldecode over them.
urldecode works on bytes. It has no idea what a host, a path, or a query string is. Hand it a complete URL and the %2F sitting inside a path segment turns into a real slash, which changes how that URL parses afterwards. The safe habit: split the URL first, then urldecode the query values, the fragment, and each path segment on their own.
Paste the encoded text, press Decode, read the result. Everything happens inside your browser tab, including the urldecode step itself.
Ctrl + Enter runs urldecode immediately. Clear empties both boxes so you can start the next string without touching the mouse.
Functions that sound alike but behave differently have burned a lot of people. These are the three mismatches that come up most often.
decodeURIComponent('a%20b') returns 'a b'. It does not touch plus signs. In query strings a + usually stands for a space, so if the value came from a form, swap + for %20 first and then run urldecode.
& and ' are HTML entities, not percent-encoding. urldecode leaves them exactly as they are. Unescaping entities is a separate job with a separate tool.
Decode values, never delimiters. If a query string holds %26, that is a literal & sitting inside the data. urldecode it and the parameter list splits into two. The same trap waits in signed payloads: decode a value that was signed in its encoded form and the signature check fails.
Three places account for most real-world urldecode usage: query strings, form bodies, and log files.
Marketing links are stuffed with encoded redirect targets. urldecode the redirect_uri or the utm_content parameter and you can see exactly where a click is heading before you follow it.
application/x-www-form-urlencoded turns spaces into + and everything else into %XX escapes. When a webhook misbehaves, running urldecode on the raw body usually beats digging through framework documentation.
Servers and export tools store query strings verbatim. To group by parameter, or to find out which character triggered a 400, urldecode that column before you sort it.
Thrown when a % is not followed by two hex digits. %ZZ, %2, or a cut-off multi-byte sequence all trigger it. Usually the string was copied incompletely, or a raw % slipped through unencoded. Fix: find the orphan %, encode it as %25, then run urldecode again.
Old-school form encoding writes a space as +. decodeURIComponent leaves + alone, so the result still shows it. Replace it manually, or use URLSearchParams, which covers both conventions.
Seeing %2520 means the data was encoded twice. %25 is %, so one urldecode gives %20 and a second gives the space. Sometimes that is deliberate — a nested URL inside a parameter — and sometimes it is a bug where two libraries each encoded the same value.
Every language has its own name for urldecode, and a couple of them quietly disagree about the plus sign.
decodeURIComponent(str) is the standard urldecode call. decodeURI(str) leaves #, ? and & alone, so it suits whole URLs rather than single values. URLSearchParams is the easier path for query strings because it also handles +.
decodeURIComponent("hello%20world") // "hello world"
new URLSearchParams("a=b+c").get("a") // "b c"
urllib.parse.unquote(s) decodes as UTF-8 by default. unquote_plus(s) also converts + to a space. parse_qs splits an entire query string into a dict in one call.
PHP ships urldecode() (handles +) and rawurldecode() (does not). Java uses URLDecoder.decode(s, StandardCharsets.UTF_8). Go offers url.QueryUnescape plus the stricter url.PathUnescape.
Every urldecode on this page happens in your browser. No request carries your input anywhere, nothing is written to a log, and no history is kept between visits. Paste access tokens, internal hostnames, or customer email addresses without worrying — the urldecode step leaves no trace off your machine.
Yes. No account, no quota, no paywalled features.
That is the whole point. As long as the original bytes were UTF-8, Chinese text and emoji come back exactly as they went in.
You can, but a %2F inside a path segment turns into a real slash and changes the structure. Split the URL first, then urldecode the pieces separately.
The data was probably encoded twice. Run urldecode one more time and the remaining escapes resolve.
Nothing practical. A few thousand characters are fine because the urldecode work never leaves the browser.