URL Encoder / Decoder
Percent-encode text for a URL or decode it back, live, with a choice of Component or Full-URL scope. Nothing is uploaded.
Runs entirely in your browser — your text never leaves your device. Encoding and decoding use the built-in encodeURIComponent/decodeURIComponent and encodeURI/decodeURI functions and a small script you can read; there are no network requests and no analytics on this tool.
Break a URL into its parts
Not an absolute URL. A relative or partial input (like /path/x or example.com/x) can't be split into scheme/host/port without guessing a base, so nothing is shown rather than a made-up parse. Add a scheme — e.g. https:// — to break it down.
Edit a query string
No parameters. Type a query string above, or add a row.
Repeated keys (e.g. two tags) are kept as separate rows in order. A bare key with no = (debug) is distinct from an empty value (debug=) — untick the = box for a bare key. This editor uses form (application/x-www-form-urlencoded) rules: a + means a space and a literal + is written %2B. That is the format HTML forms and URLSearchParams use — and it differs from the encoder at the top of this page, which follows RFC 3986 (%20 for a space, + is a literal plus).
Parsed and rebuilt entirely in your browser. Each key and value is percent-decoded and re-encoded independently, so reserved characters (& = ? # and spaces) inside a value survive a round-trip intact.
What percent-encoding actually does
A URL may only carry a restricted set of ASCII characters. Percent-encoding lets any other character ride inside one by replacing it with % followed by two hex digits of its UTF-8 byte value — a space becomes %20, an ampersand %26, and café becomes caf%C3%A9. Only the unreserved set — A–Z, a–z, 0–9 and - _ . ~ — is guaranteed to pass through untouched. You paste text on the left and get its encoded or decoded form on the right the instant you type, with no button to press.
Component vs Full URL — the scope that trips people up
Component uses encodeURIComponent and escapes the reserved delimiters too — & = ? # / : and more — so it is correct for one piece of a URL: a single query value, a path segment, or a fragment. Full URL uses encodeURI, which assumes the input is an already-structured address, leaves those delimiters intact and escapes only spaces and clearly-illegal characters. Take the query value café & tools and watch the two scopes diverge:
Both escape the spaces, but Component escapes the & to %26 while Full URL keeps it. If you drop the Full-URL output after ?q=, that surviving & is read as the start of a new parameter and your value is silently truncated to café. That single character is the whole reason the toggle exists: encode a value with Component, tidy a whole link with Full URL.
A full query string, encoded
Here is the same idea on a realistic query, encoding each value with Component and joining with literal & and = yourself:
Note 50%off becoming 50%25off (the literal % is itself escaped) and a+b becoming a%2Bb — a real plus must be escaped so it is not later mistaken for a space.
Percent-encoding reference
The reserved characters and how each scope treats them. "kept" means the character is left as-is; the hex column is its UTF-8 code if you ever do need to escape it:
| Char | Code | Component | Full URL |
|---|---|---|---|
| space | %20 | escaped | escaped |
| ! | %21 | kept | kept |
| # | %23 | escaped | kept |
| $ | %24 | escaped | kept |
| & | %26 | escaped | kept |
| ' ( ) * | %27–%2A | kept | kept |
| + | %2B | escaped | kept |
| , ; = | %2C %3B %3D | escaped | kept |
| / : ? @ | %2F %3A %3F %40 | escaped | kept |
| [ ] | %5B %5D | escaped | escaped |
The surprise line is ' ( ) *: encodeURIComponent leaves those five sub-delimiters alone even though RFC 3986 reserves them. Servers usually accept them, but a few strict signature schemes (some OAuth 1.0, older AWS signing) demand %27 %28 %29 %2A, so escape them by hand there.
Want the theory behind the buttons — reserved vs unreserved sets, how %XX hex escapes are built, and the UTF-8 multi-byte rule? Learn more in our URL encoding guide →
Decoding and malformed input
Decoding reverses the process: %C3%A9 turns back into é. The decode functions throw a URIError on a broken sequence — a lone %, or %A with only one hex digit — so this tool catches it and shows a friendly inline message rather than blanking the output, letting you see exactly where the string is truncated. A literal + is decoded as a plus, not a space, because outside HTML form data a + is a real character.
Honest limits
This tool follows the RFC 3986 %20 convention, not the form-style + of application/x-www-form-urlencoded; if you are filling a classic form field that wants + for spaces, swap it in yourself after encoding. It also does not parse a URL into parts — it applies one scope to the whole text — so to re-encode only the query string of a messy link, split it out first, encode the values, then reassemble.
Common mistakes
Double-encoding. Encoding an already-encoded string turns %20 into %2520, so the link shows literal "%20" text. Encode a raw value exactly once, where it enters the URL. Using Full URL on a value. If the value contains &, = or #, Full URL keeps them and your parameter breaks — use Component for values. Assuming + means space. decodeURIComponent does not turn + into a space; that is a form-only rule. Forgetting to escape a literal % or + inside a value, which then corrupts on the next decode. Trusting encodeURIComponent to escape ( ) ! ' * when talking to a strict parser — it will not.