URL Encoder / Decoder
Encode or decode URLs and query strings safely, entirely in your browser.
- Free, no account
- No watermark
- No usage limit
About the URL Encoder / Decoder
Most URL decoders quit after one pass. That's fine until you paste a redirect or tracking link that was encoded twice, and what comes back is another block of %253A%252F%252F you still can't read. So you decode it again, and maybe again after that, which is the loop this tool skips. Leave Fully decode on and it keeps peeling percent-encoding until the text is actually readable, then tells you how many layers deep the thing was buried. That one habit, unwrapping nested encoding in a single pass, is what saves you the decode-it-again grind the plain boxes leave you doing by hand.
The rest is what you'd expect from a URL encoder and decoder, done cleanly. Encode plain text into a URL-safe string, decode a wall of % codes back into something you can read, and do it live as you type with nothing sent to a server. Paste an auth token, a callback URL, an API parameter, whatever, it stays on your machine.
Percent-encoding itself is simple, because a URL can only carry a small set of characters safely, so everything else, a space, an ampersand, an accented letter, gets rewritten as a % followed by two hex digits before it can travel. A space becomes %20, an ampersand becomes %26. Encoding performs that rewrite, and decoding turns the codes back into the original characters.
How to use
- Pick Encode or Decode. Encode turns readable text into a URL-safe string. Decode turns percent-codes back into text. The toggle at the top sets the direction.
- Type, paste, or drop a file. Results appear in the box below on every keystroke, no convert button. You can also drag a
.txtor log file straight onto the input to load its contents. - For decoding, leave Fully decode on. It unwraps every layer of encoding at once, so a double or triple-encoded URL comes back clean instead of half-decoded. If a value was only encoded once you won't notice a difference. If it was nested, a note tells you how many layers it stripped and shows each pass.
- Turn on Treat + as a space when you're decoding form data, where a plus sign stands for a space. Leave it off for normal URLs, where a plus is a literal plus.
- For encoding, choose the scope. By default it encodes a single value with
encodeURIComponent, which is what you want for one query parameter or path piece. Tick Encode the whole URL to switch toencodeURI, which leaves the structure of a complete address alone. Tick Spaces as + if you're building a form body rather than a plain URL. - Copy the result, Swap to feed it back into the input, or Clear to start over. Swap flips the mode too, so it's a quick way to round-trip a value and confirm it survives.
Paste something malformed while decoding, like a lone % or a truncated escape, and the tool shows a short message and keeps running. Fix the bad part and the result updates.
Why one decode pass often is not enough
Double encoding is more common than it looks, and it's the thing this tool is built to handle. It happens when a value that's already encoded gets encoded a second time, usually by two layers of a stack that don't know about each other. A link shortener wraps a URL that a marketing platform already wrapped. An HTTP client encodes a parameter the framework encoded first. Each layer escapes the % signs of the layer below it, so %20 becomes %2520, and %2520 becomes %252520.
Decode that once and you don't get text, you get the next layer down. A plain decoder hands it back and calls it done, which is why people end up copying the output back into the input and hitting decode again, over and over, counting %25 sequences by eye. Fully decode does that counting for you, running the unwrap repeatedly until the string stops changing, stopping at the readable form, and reporting the depth. It also stops safely if a layer isn't valid encoding, so you get back the furthest it could reasonably go rather than an error.
The layer view under the result is the part that actually helps when you're debugging. It shows each pass in order, so you watch a redirect URL emerge from its wrapper one step at a time. If a tracking link buried the real destination three levels deep, you'll see all three. And decoding a suspicious link is how you find out where it truly points before you go anywhere near it.
There's one caveat, and it's rare. If a value legitimately contains a %25 that was meant to survive, aggressive unwrapping can strip a layer you wanted to keep. The layer view makes that obvious when it happens, and you can switch Fully decode off and do a single pass instead.
encodeURIComponent vs encodeURI
This is the distinction developers actually search for, and getting it wrong causes real bugs. Both encode text for a URL, but they differ in how much they escape.
encodeURIComponent is for a single piece of data, one query value or one path segment. It escapes the structural characters too, the /, ?, &, = and the rest, because inside a single value those are data, not syntax. This is the right choice nearly every time you drop user input, a search term, a filename, or a token into a bigger URL, and it's the default here.
encodeURI is for a complete address that's already assembled correctly. It deliberately leaves the structural characters alone so it doesn't break the URL you handed it. Reach for it only when you've got a whole URL with a raw space in it and you want to clean that up without disturbing the rest.
The classic failure is encoding a full URL with encodeURIComponent, which mangles the :// and every slash into percent-codes and leaves you a string no server can use. The opposite mistake, encoding a single value with encodeURI, leaves an & inside your value unescaped, so the server reads one parameter as two. Tick Encode the whole URL to flip between the two and watch what changes.
Spaces, plus signs, and form data
The most common confusion after that is why a space is sometimes %20 and sometimes +. Both are right, they just come from different places. Standard URL encoding writes a space as %20, which is valid anywhere in a URL. HTML forms, using the application/x-www-form-urlencoded format, write it as +. That convention is older than the modern URL rules and only means "space" inside a form body. In a normal URL path a + is a literal plus sign.
This matters when you decode. If a value came from a form and you decode it as a plain URL, every + stays a + instead of turning back into a space, and your text is quietly wrong. Turn on Treat + as a space and the tool reads plus signs the way a form decoder does. Spaces as + on the encode side produces the same form flavor. Leave both off for ordinary URLs.
Frequently asked questions
How many layers of encoding can Fully decode unwrap?
Up to twenty passes, which is far past anything you'll meet in the wild, since real nesting almost never goes beyond three. It stops the instant a pass produces the same string it started with, so a value encoded once takes one pass, a double-encoded value takes two, and so on. The note above the result reports the exact count, and the layer view lists each pass, so you can confirm it went as deep as you expected and no further.
Why did decoding stop before the text looked fully readable?
Because a pass ran into something that isn't valid percent-encoding, so the tool kept the last good result instead of throwing an error. Usually that means what's left really is the decoded value and just happens to contain a % that was never an escape. If it looks wrong, check the input for a stray % or an escape missing a hex digit, like %E with nothing after it.
Is this the same as Python's quote or PHP's rawurlencode?
Close. encodeURIComponent lines up with Python's urllib.parse.quote and PHP's rawurlencode, which all use %20 for a space. The form flavor, with + for spaces, matches Python's quote_plus and PHP's urlencode. So if a backend encoded a value one way and you're checking it here, pick the matching option, Spaces as + for the form style or leave it off for the plain style, and the output should agree.
Why do some characters never get encoded?
A fixed set of characters is always safe in a URL and gets left alone, the letters A to Z, the digits 0 to 9, and four symbols: hyphen, period, underscore, and tilde. Everything else, spaces, punctuation that carries structural meaning, and anything non-ASCII, gets a percent-code. Encoding a safe character anyway isn't wrong, just pointless, so the encoder leaves them readable to keep the output shorter.
Why does one accented letter turn into several percent codes?
Because encoding works on bytes, and a non-ASCII character is more than one byte. The character is turned into bytes with UTF-8 first, then each byte becomes its own %XX code. The letter é is two bytes, so it comes out as %C3%A9. A Chinese character is usually three bytes and gives three codes, and an emoji is four. Plain ASCII letters are a single byte, which is why they only ever make one code.
Is anything I paste sent to a server?
No. Everything runs in your browser and the text never leaves the page, no upload and no logging. That's on purpose, because the things people paste into a URL tool, auth tokens, callback URLs, private API parameters, tend to be sensitive. Close the tab and it's gone.
Can I share a decoded result with someone?
Yes. The Share button copies a link that carries your current input and settings, so whoever opens it lands on the same result you're looking at, already worked out. The Embed button hands you a snippet to drop the live tool onto your own page. Both stay the same private, in-browser tool, the link just reproduces your setup.