🔗 URL Encoder Decoder
Encode or decode a URL, a query string or a single value — percent-encoding (RFC 3986), + for spaces in form data, and a lenient decoder that tells you which escapes were invalid instead of throwing. Any URL is also broken into scheme, host, path, query parameters and fragment. Runs in your browser.
🔗 URL encoder / decoder
Encoding and decoding happen with the browser's own encodeURIComponent / decodeURIComponent primitives, so what you see here is exactly what fetch() or your framework will produce.
🧩 Parsed URL
🔍 Query parameters (decoded)
📖 Every percent escape in the input
🌍 Non-ASCII characters and their UTF-8 bytes
🔗 What is percent-encoding?
A URL may only contain a small set of ASCII characters. Everything else — spaces, &, ?, Cyrillic, Chinese, emoji — has to be written as a percent-encoding: a percent sign followed by the two hex digits of the byte. A space is %20, & is %26, the ampersand-free # is %23. Multi-byte characters are encoded byte by byte in UTF-8, so 中 (U+4E2D) becomes %E4%B8%AD and 😀 (U+1F600) becomes %F0%9F%98%80.
The rules live in RFC 3986, which also defines how the parts of a URI fit together. Two practical consequences follow from it:
- A reserved character only becomes reserved in a particular position. A
/in a path is a separator; a/inside a query value must be encoded as%2Fif it is meant literally. - Encoding is not encryption and not compression. Decoding is always reversible, and this tool does it locally.
📚 Reserved vs unreserved characters
Only the unreserved set may appear literally in a URL: A–Z, a–z, 0-9, -, _, ., ~. Everything else is a candidate for escaping, but implementations differ by one notch — and that notch causes most "why is my signature invalid?" bugs:
| Function / mode | Escapes | Leaves alone |
|---|---|---|
encodeURIComponent (Component mode) |
everything except unreserved + ! ' ( ) * |
A-Z a-z 0-9 - _ . ~ ! ' ( ) * |
| Strict RFC 3986 (Strict mode) | also ! ' ( ) * |
A-Z a-z 0-9 - _ . ~ — this is what AWS SigV4 and OAuth 1.0 expect |
encodeURI (Whole URL mode) |
spaces, non-ASCII, control characters | reserved: : / ? # [ ] @ ! $ & ' ( ) * + , ; = |
x-www-form-urlencoded (Form mode) |
same as Component, then %20 → + |
as Component, but spaces become + |
If a signature check fails on exactly the characters ! ' ( ) *, you are comparing Component output with a Strict-mode signature — switch the mode and try again.
🎛️ Which mode should I use?
- Component — one value that goes into a query parameter, path segment or form field. This is the default and matches JavaScript's
encodeURIComponent. - Strict RFC 3986 — the same, plus
!,',(,),*escaped. Required by some signature schemes and by a few strict servers. - Whole URL — paste a complete address containing a space or a non-ASCII character and get back a valid URL with the structure intact.
- Form data — for
application/x-www-form-urlencodedbodies and classic HTML form posts, where a space is a+.
Decoding uses the same selector: in Form mode a + becomes a space, in the other modes it stays a plus sign (which is why a+b survives a round trip in Component mode but turns into a b in Form mode).
🚀 How to use this tool
- Paste a URL, a query string (
?a=1&b=2) or a single value into the input box. - Pick the mode that matches where the value is going.
- Press Encode or Decode. The output box holds the result, ready for its copy button.
- Read the panels underneath: the input is also parsed into scheme, host, port, path, query and fragment, the query string is expanded into a parameter table, every percent escape already present is decoded for you, and non-ASCII characters are shown with the exact UTF-8 bytes they will occupy.
- If the input looks double-encoded (
%2520), Decode will tell you and decode it twice.
🐛 Common encoding mistakes
- Encoding the whole URL with encodeURIComponent.
https://a.com/b?c=dbecomeshttps%3A%2F%2Fa.com%2Fb%3Fc%3Ddand your server sees a path that does not exist. Encode the values, not the address. - Double encoding. Encoding in the client, then again in a proxy or an SDK, turns a space into
%2520. When an API echoes back%20as literal text, look for a second encode step. - Mixing
+and%20. A+in a path is a literal plus. Decoding form data with a component decoder leaves plus signs everywhere, and decoding a path with a form decoder turns every plus into a space. - Encoding reserved characters a second time.
%2Fin a path is a literal slash; some servers decode it back into a separator and re-route the request. That is a real (and sometimes exploitable) difference — keep it in mind when you build URL rewrite rules. - Assuming UTF-8. Older Latin-1 systems produce
%E9foréwhere UTF-8 needs%C3%A9. The escape table above flags byte sequences that are not valid UTF-8.
💼 Use cases
- API debugging: see what your request actually contains — a query parameter that should be
name=John Doebut arrives asname=John+Doeorname=John%2520Doeexplains a lot of 400s. - Signed URLs: CDN and cloud storage links embed an encoded signature; a single mis-escaped character invalidates the signature.
- Building links by hand: generate a properly encoded query string for an email, a spreadsheet or a tracker without writing a script.
- Reading search URLs: decode the
q=parameter of a search engine or an analytics export. - Log forensics: decode the requesting URL out of an access log line, including the spaces and the non-ASCII path.
- OAuth / OIDC work:
redirect_uri,stateandscopeall travel percent-encoded, and half of all redirect_uri_mismatch errors are an encoding difference.
❓ Frequently asked questions
What is the difference between encodeURIComponent and encodeURI?
encodeURIComponent escapes everything except A-Z a-z 0-9 - _ . ! ~ * ' ( ) and is meant for a single value. encodeURI keeps the reserved characters so an entire URL stays a URL. Use Component mode for a value and Whole URL mode for an address.
Should a space be %20 or +?
In a path or a modern query string, %20. In application/x-www-form-urlencoded bodies and HTML form posts, +. The Form mode encodes to + and the Form decode mode turns + back into a space.
What about double encoding?
It shows up as %25 followed by two hex digits — %2520 where a space was expected. This tool detects the pattern and decodes twice, showing you the intermediate result.
Why does decoding sometimes fail?
decodeURIComponent throws on a truncated escape such as %E4%B8 or on bytes that are not valid UTF-8. This decoder is lenient by default: valid escapes are decoded, malformed ones are left untouched and listed in the status line, so you can still see the rest of the payload.
Is my URL sent to a server?
No. Encoding, decoding, URL parsing and the byte tables all run in your browser. Signed URLs with credentials in them are safe to paste here — nothing leaves the page.