URL Encode / Decode
Percent-encode or decode text, or break a full URL into its parts.
Private by design. Your input never leaves this browser. Conversions run locally on your device.
What this tool handles
- Detects what to do with the input: an absolute URL is inspected, text carrying percent escapes is decoded, anything else is encoded.
- Encoding uses encodeURIComponent for a single value or encodeURI for a whole URL.
- "+" can be treated as a space when decoding, which is the form-submission rule.
- Inspecting a URL breaks out protocol, host, port, path, query parameters and hash.
Example
Input
hello world&lang=cs
Output
hello%20world%26lang%3Dcs
When you would use it
- One value going into a query string — Component scope escapes &, = and / inside the value, which is what stops a search term or a filter expression from ending the parameter early.
- Reading the redirect_uri out of an authorize URL — Inspecting an OAuth URL decodes each parameter once, so redirect_uri and scope come back readable. A value that is still full of escapes afterwards was encoded twice on the way in.
- A link that only needs its spaces fixed — Whole-URL scope leaves : / ? # & = alone and escapes only what is illegal, which is the right treatment for an address pasted out of a document or a chat message.
- A form body copied from the network tab — An application/x-www-form-urlencoded body writes spaces as +, so switch the plus option on before decoding it — and leave it off for a path segment, where + is an ordinary character.
Common questions
Why are ! ' ( ) * ~ left unescaped?
encodeURIComponent exempts them, along with letters, digits and - . _ , and they are legal in a query value. A stricter consumer, such as an RFC 3986 or OAuth 1.0 signature, wants them escaped, so percent-encode those few by hand.
Is a space %20 or a plus?
Encoding here always produces %20. A plus means a space only under the form-submission rules, which is why decoding it that way is an explicit option rather than the default.
Why did decoding leave some escapes behind?
Whole-URL scope refuses to decode the escapes that stand for reserved characters — %2F, %3F, %26 and the rest — because doing so would change how the address parses. Switch to component scope to decode everything.
Why does the parameter count exceed the number of keys shown?
The count covers every name-value pair, while the parsed object holds one entry per name. With ?tag=a&tag=b it counts two and shows tag once, with the last value winning, so check the raw query string when repeated keys matter.
Related tools
- JWT Decoder — Decode a JSON Web Token header and payload locally. Signatures are not verified.
- Base64 Encode / Decode — Encode and decode Base64 and Base64URL with correct UTF-8 handling.
- cURL → code — Translate a cURL command into fetch, axios or Python requests code.
- Hash Generator — Compute SHA-256, SHA-384, SHA-512, SHA-1 and MD5 digests of text or a file.