URL Encoder & Decoder
Percent-encode a value for a query string, or decode percent-escapes back to readable text, entirely in your browser.
What is a URL encoder?
A URL encoder rewrites characters that have a structural job in a URL, or no legal place in one, as a percent sign followed by two hex digits. A space becomes %20. An ampersand becomes %26. That is percent-encoding, and it exists because a URL is a structure before it is text. The ? opens the query string, each & separates one parameter from the next, and = splits a name from its value. Put a raw ampersand inside a value and the parser cannot know you meant a literal character rather than the start of another parameter.
This page runs both directions. Encode turns plain text into percent-escapes, Decode turns them back, and the conversion happens as you type with a live character count under each panel. Encode mode lets you choose between the two encoders JavaScript ships with, encodeURIComponent and encodeURI, because they escape different sets of characters and picking the wrong one is the most common way this goes wrong. Decode mode has a checkbox for the other well-known trap: whether a plus sign means a plus or a space.
When to use it
The trigger is usually a link that broke. A search term with an ampersand truncated the query string. A file path with spaces produced a 400 from a gateway that would not take a raw space. A customer name arrived in analytics split across three parameters. Paste the value in, encode it, and the fault is either obvious or ruled out in seconds. The other direction comes up as often, because something arrived already encoded and now has to be read. Server logs store the request line exactly as received, so a query string full of %3A and %2F is what you find when you go looking for what a client sent.
OAuth deserves its own mention, because redirect_uri is where most developers meet percent-encoding for the first time. The entire callback URL, scheme and slashes and its own query string included, is one parameter value inside a bigger URL, so everything in it that would otherwise be structural has to be escaped. Providers compare what you send against the registered value byte for byte, and both an unescaped slash and an extra layer of encoding fail that check with the same unhelpful redirect_uri_mismatch. If the value you decode turns out to be JSON, the JSON Formatter will lay it out for reading and the JSON Parser will tell you whether it is valid.
How this tool works
Encoding runs your text through one of two built-in encoders. encodeURIComponent is the default and the safer choice, because it escapes everything outside the unreserved set: letters, digits, and the nine punctuation marks - _ . ! ~ * ' ( ). The reserved delimiters go with it, so / ? : @ & = + $ # all come back as escapes. Use it for one value, meaning a single query parameter or a single path segment. encodeURI leaves those delimiters alone on purpose, because it is built for a URL that is already assembled and whose structure has to survive. Send https://example.com/a?b=c through encodeURI and nothing changes. Send it through encodeURIComponent and every colon, slash, question mark, and equals sign is escaped. Correct when the URL is itself a parameter value, wrong when it is the address you are about to request.
Decoding uses decodeURIComponent, which reverses the output of either encoder. It reads each %XX as one byte, collects them, and interprets the run as UTF-8, which is what matters outside ASCII: an accented Latin letter encodes to two escapes and an emoji to four. Escapes are consumed one layer at a time, and that is what makes double encoding recognisable. Pass a value through an encoder twice and its %20 becomes %2520, because the percent sign of the first escape is itself encoded to %25 on the second pass. Decode once for the singly-encoded text, again for the original.
The plus sign is a real ambiguity and this tool refuses to guess. decodeURIComponent treats + as a literal plus, and that is the default here. HTML form submissions follow the application/x-www-form-urlencoded rules instead, where a space is written as +. Tick "Read + as a space" and every plus becomes a space before decoding. Right for a form post, wrong for a phone number in international format. An escaped plus, %2B, survives either setting, because the substitution runs before the decode rather than after it. Input that cannot be decoded gets an explanation rather than an empty box or a console error: a percent sign not followed by two hex digits is quoted back at you, and escapes whose bytes are not legal UTF-8 get their own message, since the fix is different. All of it runs locally. Nothing you paste is uploaded or stored, which matters here more than on most utilities, because the URLs people decode carry session tokens, signed links, and the occasional API key that somebody put in a query string by mistake.
Examples
A search term going into a query string
InputBen & Jerry's ice creamOutputBen%20%26%20Jerry's%20ice%20creamEncoded with encodeURIComponent. Left raw, everything after the ampersand reads as a second parameter and the value truncates to "Ben". The apostrophe is in the unreserved set and passes through untouched.
A whole URL, encoded with encodeURI
Inputhttps://example.com/reports/Q3 results.pdf?ref=email&utm_campaign=fall saleOutputhttps://example.com/reports/Q3%20results.pdf?ref=email&utm_campaign=fall%20saleOnly the two spaces changed. The slashes, the question mark, and both equals signs are structural here, so encodeURI leaves them and the result is still a working address.
The same URL as a single parameter value
Inputhttps://app.example.com/auth/callback?tenant=acme&next=/dashboardOutputhttps%3A%2F%2Fapp.example.com%2Fauth%2Fcallback%3Ftenant%3Dacme%26next%3D%2FdashboardEncoded with encodeURIComponent. This is the shape an OAuth redirect_uri needs before it goes into the authorize URL, and if it differs from the registered value by one escaped slash the request is rejected.
A double-encoded value pulled out of a log
Inputq=Acme%2520Corp%2520%2526%2520SonsOutputq=Acme%20Corp%20%26%20SonsOne pass strips one layer, so the result is still encoded text. The %2520 sequences are the giveaway. Paste the output back in and decode again to reach q=Acme Corp & Sons.
Form-encoded input, with plus read as a space
Inputname=Ada+Lovelace¬e=2+2%3D4Outputname=Ada Lovelace¬e=2 2=4Decoded with "Read + as a space" ticked. Unticked you get name=Ada+Lovelace¬e=2+2=4, which is what decodeURIComponent does alone. Neither is wrong in general, which is why it is a checkbox.
Input that cannot be decoded
Inputdiscount=20%OutputThe % at the end of this input is not a valid percent-escape. A % has to be followed by two hex digits, like %20 for a space or %3F for a question mark. If you meant a literal percent sign, write it as %25.A percent sign that does not start an escape makes decodeURIComponent throw a URIError. The tool catches it and names the problem instead of showing you nothing.
Frequently asked questions
How do I encode a URL online?
Leave the mode on Encode and paste your text into the left panel. The percent-encoded version appears opposite as you type. Pick encodeURIComponent for one value that will sit inside a URL, encodeURI for a whole assembled URL whose slashes and question mark should be left alone. Use Copy to take the result. No upload, no account.
What is the difference between encodeURI and encodeURIComponent?
encodeURIComponent escapes the reserved delimiters / ? : @ & = + $ # along with spaces and everything else outside the unreserved set. encodeURI leaves those delimiters intact, because it assumes you handed it a complete URL whose structure must survive. Use encodeURIComponent for a single query parameter or path segment, encodeURI when the string is already a working address and you only want its illegal characters fixed. Get this backwards and you end up with either a URL that no longer parses or a value that leaks into the query string.
Which characters need to be encoded in a URL?
Exactly 71 survive encodeURIComponent untouched: A-Z, a-z, 0-9, and the nine punctuation marks - _ . ! ~ * ' ( ). Everything else should be encoded, including the space, the reserved delimiters / ? : @ & = + $ #, the percent sign itself, quotes, angle brackets, braces, the pipe, and the backslash. Anything outside ASCII becomes its UTF-8 bytes, one escape per byte, so a single character can turn into four escapes.
Why does a space sometimes decode as a plus sign?
Two specifications are in play. Percent-encoding writes a space as %20. The application/x-www-form-urlencoded rules that HTML forms use write it as +, and that convention spread into a great many query-string builders. decodeURIComponent implements only the first, so a form-encoded value comes back with visible plus signs where spaces should be. Tick "Read + as a space" in Decode mode to apply the form rule instead, and keep it off when the value could contain a real plus.
What does %2520 mean in a URL?
It means the value was encoded twice. %20 is a space and %25 is a percent sign, so %2520 is the encoded form of the text "%20" rather than of a space. Finding it in a redirect URL or a log line almost always points at a value your code encoded and a framework, proxy, or SDK then encoded again. Decode once here and you get %20 back, which confirms it. Then remove one of the two encoding steps.
Can someone fix the encoding bugs upstream for us?
Yes. A recurring encoding bug is a symptom, and the fix almost never lives in the browser tab where you spotted it. If your team decodes callback URLs out of logs to debug an OAuth integration, or hand-checks that a partner feed escapes its parameters properly, that work belongs in a validator or a test rather than a browser tab somebody has to remember. Point Zinc Online Solutions at the integration and we will find where the extra escape is being added.