URL encoder
Processed in your browser · nothing is uploaded
Two encodings, because they do different jobs: component encoding escapes &, =, / and ? so a value can sit inside a query string; whole-URL encoding leaves those alone because they are the structure.
How to use the url encoder
Using the wrong one is the classic bug. Encoding a whole URL with component encoding turns https://x.com/a?b=c into https%3A%2F%2Fx.com%2Fa%3Fb%3Dc, which no browser will follow. Encoding a query value with whole-URL encoding leaves an ampersand in it, which splits the parameter and truncates the value with no error anywhere: the data simply stops at the ampersand. Rule of thumb: component encoding for anything going into a URL, whole-URL encoding for a URL you are cleaning up. The sample above makes the split visible. search?q=a b&filter=x/y comes back from component encoding as search%3Fq%3Da%20b%26filter%3Dx%2Fy, with every structural character escaped, and from whole-URL encoding as search?q=a%20b&filter=x/y, with only the space touched.
Percent-encoding works on bytes, not on letters, and the bytes are UTF-8. An é becomes %C3%A9, two escapes for one character, and an emoji becomes four. So a length limit anywhere in a URL is a limit on bytes: a 100-character query value in Japanese is 300 bytes once encoded. It also means that decoding is where a mismatched character set shows up, as replacement characters rather than as an error.
Three traps account for most of the confusion. Both encoders escape an existing % as %25, which is correct and is why encoding twice compounds: a b becomes a%20b and then a%2520b, and one decode only gets you back to a%20b; a value that survived two systems usually needs two decodes. Whole-URL encoding leaves # alone as structure, so a genuine hash inside a value has to be escaped by hand or everything after it becomes the fragment and never reaches the server. And decoding treats + as a space before anything else happens, which is correct for form-encoded query data and wrong for a path or a Base64 blob: C++ decodes to C followed by two spaces. Encoding with the component encoder first avoids that, because it writes a plus as %2B.
What people use it for
- Escaping a search term before it goes into a query string
- Reading a redirect URL that has been encoded twice over
- Working out why a parameter value stops at the ampersand
- Turning a percent-encoded path from a server log back into text
- Putting an email address or a filename into a link safely
Questions
Component encoding escapes the structural characters too, for values going into a URL. Whole-URL encoding leaves them, for a URL you are cleaning up.
Component. A value has to be safe next to the & and = that separate parameters, and only component encoding escapes those.
An unescaped ampersand in the value split the parameter. Everything after it was read as the next parameter, so the tail of your value disappeared without an error. Use component encoding for values.
In form-encoded data yes, in a path segment no. This decoder treats it as a space, which is right for query strings and wrong for anything else.
Both pluses were read as spaces. Percent-encode the value first and they become %2B, which survives a round trip intact.
Percent-twenty is correct everywhere. Plus is a convention that belongs only to application/x-www-form-urlencoded, which is what an HTML form submits and what most query strings imitate.
The percent signs from the first pass get escaped by the second, so a b becomes a%2520b. It is the most common cause of a redirect parameter arriving as visible gibberish.
Run Decode twice. One pass takes a%2520b to a%20b, and the second takes it to a b.
A percent sign that is not followed by two hexadecimal digits is not a valid escape, so 100% done cannot be decoded. Escape the literal percent as %25 first.
Letters, digits, and - _ . ! ~ * ' ( ). Everything else is escaped.
Not quite. RFC 3986 lists only - . _ ~ as unreserved alongside letters and digits, and reserves ! ' ( ) *. Leaving those five unescaped is safe in practice and occasionally not in a strict parser, so escape them by hand if you are feeding something fussy.
No. # is structure, so it is left alone. A hash inside a value has to become %23 or everything after it is treated as the fragment and never sent to the server.
Because encoding works on UTF-8 bytes. é is two bytes, so it is %C3%A9. Most emoji are four bytes and become four escapes.
Bytes, after encoding. Non-Latin text roughly triples on the way in, so a value that looks short can still overrun a server or CDN limit.
Component-encode it to %2F. Be aware that some servers and proxies normalise or reject an encoded slash inside a path, so a query parameter is the safer place for one.
With the component encoder, yes. With whole-URL encoding, no: a + passes through untouched and comes back as a space.
They do not use percent-encoding at all. A host is converted with punycode, so münchen.de travels as xn--mnchen-3ya.de. Only the path, query and fragment are percent-encoded.
No. Percent-encoding is for URLs. A JSON request body carries its own escaping rules and needs none of this.
Yes, and that is usually the right move: paste only the value, component-encode it, and paste the result back into the address you are assembling.
No. Everything is encoded and decoded in this page.