About URL Encoder & Decoder
URL Encoder & Decoder applies percent-encoding in two distinct scopes: URL component, for a single value such as a query parameter or a path segment, and full URI, for a complete address whose separators must survive. The input pane validates percent sequences as you type, so a malformed value is flagged before you run the conversion.
Percent-encoding replaces a byte with a percent sign and two hexadecimal digits, and the only real question is which characters count as data and which count as structure. In a complete URI the slash, question mark, ampersand, and hash are structure and must stay literal; inside a single value those same characters are data and must be escaped, or they will silently re-shape the URL. Non-ASCII characters are first encoded as UTF-8 and then percent-encoded byte by byte, which is why one Chinese character becomes nine characters of escape sequence.
How to use this developer tool
- Choose Encode or Decode.
- Choose the scope: URL component for a single value, full URI when you are handling an entire address.
- Paste the value and watch the status line; in decode mode it tells you immediately whether the percent sequences are well formed.
- Run the conversion and check the reserved characters in the result, particularly &, =, ?, /, and #.
- Assemble the final URL from literal separators plus component-encoded values, rather than encoding the finished string.
Worked example: a redirect parameter
A callback URL has to be carried inside another URL's query string. Only one of the two scopes produces a link that survives.
https://example.com/cb?state=a b&next=/homeURL component : https%3A%2F%2Fexample.com%2Fcb%3Fstate%3Da%20b%26next%3D%2Fhome
Full URI : https://example.com/cb?state=a%20b&next=/homeOnly the component form can be pasted after redirect=, giving https://sso.example.com/login?redirect=https%3A%2F%2Fexample.com%2Fcb%3Fstate%3Da%20b%26next%3D%2Fhome. The full-URI form keeps the ampersand literal, so the receiving server reads next=/home as a parameter of its own login URL and the callback loses half of itself.
How the two scopes treat each character
Both scopes encode a space and every non-ASCII byte. They differ only on the reserved characters that give a URL its structure.
| Character | URL component | Full URI | Why it matters |
|---|---|---|---|
| space | %20 | %20 | Never legal unencoded in a URL |
| & | %26 | & | Separates query parameters |
| = | %3D | = | Separates a parameter name from its value |
| ? | %3F | ? | Starts the query string |
| / | %2F | / | Separates path segments |
| # | %23 | # | Starts the fragment, which is never sent to the server |
| + | %2B | + | Read as a space by form decoders |
| : and @ | %3A and %40 | : and @ | Scheme and userinfo separators |
| % | %25 | %25 | Must be escaped, or decoding fails |
| 中 | %E4%B8%AD | %E4%B8%AD | Encoded as UTF-8 bytes, three per character |
| - . _ ~ ! * ' ( ) | unchanged | unchanged | Unreserved or sub-delimiters left alone by both |
Troubleshooting
A parameter arrives at the server truncated at the first ampersand.
Why it happens The value was encoded in full-URI scope, or not encoded at all, so its own ampersand was read as a separator by the receiving server.
Fix Encode each value in component scope and join the pieces yourself. In code, let URLSearchParams or the equivalent build the query string so this cannot happen.
Spaces come back as plus signs, or plus signs come back as spaces.
Why it happens Two encodings are in play. Percent-encoding writes a space as %20, while application/x-www-form-urlencoded writes it as +. Decoding here never converts + to a space, because in a path or a fragment a plus is a literal character.
Fix For form-encoded data, replace + with %20 before decoding, or parse it with URLSearchParams, which applies the form rules.
Decoding reports that the encoding is invalid.
Why it happens A percent sign is not followed by two hexadecimal digits, or a multi-byte UTF-8 sequence is incomplete. This is common when a log truncated the value mid-escape, or when a Windows path or a literal percentage figure was pasted.
Fix Look at the last percent sign in the string; if it has fewer than two digits after it, the value was cut. Escape a literal percent as %25 before encoding text that contains one.
The value contains %2520 or %25 sequences you never wrote.
Why it happens It was encoded twice, usually once by the application and once by a gateway or a client library that assumed the value was raw.
Fix Decode once and check: if the result still contains valid escapes, the value was double-encoded. Fix the layer that encodes an already-encoded value rather than compensating downstream.
A path with non-ASCII characters works in the browser but not on the server.
Why it happens The address bar displays the decoded form while sending percent-encoded UTF-8. A server that decodes with a different character set turns those bytes into mojibake.
Fix Compare the raw request line in the server log with the encoded form produced here. Configure the server to decode URLs as UTF-8, which is what every browser sends.
When this tool is the right choice
- Building a redirect, callback, or state parameter that has to carry a complete URL.
- Reading a percent-encoded URL out of a log line or an error message.
- Explaining a signature mismatch, where the signing side and the sending side encoded the same value differently.
- Repairing a link copied out of a chat window with spaces or line breaks in it.
When to use something else
- Building form bodies where a space must become a plus sign; use URLSearchParams or your HTTP client's form encoder.
- Escaping text for a web page. Markup needs entity escaping; use the HTML Entity Encoder & Decoder.
- Checking whether a URL is reachable or safe. This tool never opens a connection; the Website Check tool answers reachability.
Privacy and data handling
Encoding and decoding use the browser's own URI functions inside this tab. The tool never fetches the address, so it cannot tell you whether a link resolves, redirects, or is safe to open, and nothing you paste is transmitted or stored. URLs copied from a browser frequently carry session identifiers and single-use tokens in their query strings, so redact those before sharing the value anywhere.
Related developer tools
Frequently asked questions
When do I use component scope instead of full URI?
Use component scope for anything that is a single value: a query parameter, a path segment, a fragment identifier. Use full URI only when you already hold a complete, correctly structured address and just need to escape spaces and non-ASCII characters in it.
Why is a plus sign not decoded as a space?
Because that rule belongs to form encoding, not to URIs. In a path, a fragment, or a general query value, a plus is a literal plus, and converting it would corrupt data such as Base64 payloads and phone numbers.
Which characters are never encoded?
The unreserved set, being letters, digits, hyphen, period, underscore, and tilde, plus the sub-delimiters ! * ' ( ) that the browser's encoder leaves alone. Everything else is either encoded in both scopes or only in component scope.
How are Chinese characters and emoji encoded?
They are converted to UTF-8 bytes and each byte becomes a percent escape, so a Chinese character produces nine characters and an emoji twelve. That expansion is why long non-ASCII URLs hit length limits quickly.
Is percent-encoding a security control?
No. It preserves structure, it does not sanitize. A decoded URL can still point somewhere hostile, and a value that was safely encoded can still be dangerous once your application interprets it.
Should I encode the whole URL before putting it in a link?
No. Encoding a finished URL escapes its own separators and breaks it. Encode the values, then assemble the URL from literal separators and encoded parts.