URL encoder / decoder
Percent-encode or decode URLs and query parameters. Choose component or full-URI mode. Runs in your browser.
https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Dhello%20world%26lang%3Dru
What this URL encoder does
The tool percent-encodes text so it can be placed safely in a URL, and decodes
%XX sequences back to characters. It uses the browser’s own
encodeURIComponent / encodeURI and their decode counterparts, so the result
is byte-for-byte what your JavaScript would produce — no custom tables. Two
modes cover the two real-world jobs: encoding one value (component) and
tidying a whole URL (full URI). Output updates as you type; nothing leaves
your browser.
How to use it
- Choose Encode or Decode.
- Pick a Mode:
component (escape all)for a query parameter, path segment or anything that will be pasted into a URL;full URI (keep / : ?)when the input already is a URL and you only want to fix spaces and non-ASCII. - Paste the text. The default sample is a URL with a space and a
&in a value — try switching modes to see the difference. - Copy the output. In Decode mode an invalid sequence shows a red error instead of partial output.
Which characters each function encodes
| Character class | encodeURIComponent (component) | encodeURI (full URI) | escape() (legacy) |
|---|---|---|---|
A–Z a–z 0–9 | kept | kept | kept |
- _ . ! ~ * ' ( ) | kept | kept | - _ . * kept, rest encoded |
; , / ? : @ & = + $ # | encoded | kept | + / @ kept, rest encoded |
| space | %20 | %20 | %20 |
" < > \ ^ [ ] { } | and the backtick | encoded | encoded | encoded |
ü (non-ASCII) | %C3%BC (UTF-8) | %C3%BC (UTF-8) | %FC (Latin-1) |
€ or emoji | UTF-8 bytes | UTF-8 bytes | %u20AC — not valid in URLs |
escape() is deprecated and only listed because you still meet its %uXXXX
output in old code; nothing modern will decode it. Note also that encodeURI
does not encode #, so a # inside a value will be read as the fragment
separator — use component mode for values.
Worked examples
Input: https://example.com/search?q=hello world&lang=ru
| Mode | Output |
|---|---|
| component | https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Dhello%20world%26lang%3Dru |
| full URI | https://example.com/search?q=hello%20world&lang=ru |
The second is a working link. The first is what you want if the whole URL is
itself a parameter, for example a redirect_uri or a ?url= value — then the
inner ? and & must not be mistaken for the outer query’s separators.
A value that contains a separator, price=1&tax=0.2, becomes
price%3D1%26tax%3D0.2 in component mode, so a server reading ?filter=...
receives the entire string in one parameter instead of three. In JavaScript the
URLSearchParams API does this for you, and additionally writes spaces as +:
const params = new URLSearchParams({ q: 'hello world', lang: 'ru' });
params.toString(); // "q=hello+world&lang=ru"
Decoding gotchas
+is not a space todecodeURIComponent; it stays+. Only form-encoded query strings use+for space. Replace+with%20first if the data came from an HTML form, or parse it withURLSearchParams, which does it for you.- Full-URI decode keeps reserved sequences.
decodeURIdeliberately leaves%2F,%3F,%23and the other reserved characters encoded, because turning them back into/,?,#would change the URL’s structure. Use component mode when you want everything decoded. - Malformed input throws.
%E0%A4%A(truncated),%zz(not hex) or a lone%at the end all produce the “Invalid percent-encoding” error rather than a best-effort string. - Double encoding shows up as
%25in the input. If decoding once still leaves%20sequences behind, something upstream encoded the value twice.
Related tools and snippets
- Base64 encoder / decoder — standard Base64 uses
+and/, which need encoding before they go in a query string. - HTML entity encoder / decoder — a URL placed in an
hrefattribute additionally needs&written as&. - JWT decoder — tokens use Base64URL precisely to avoid percent-encoding.
- Regex tester — build the pattern that extracts a parameter from a URL.
- QR code generator — encode a finished URL into a scannable code.
FAQ
What is the difference between component and full-URI mode?
Component mode (encodeURIComponent) escapes every reserved character including / ? : & = and #, so it is right for a single query value or path segment. Full-URI mode (encodeURI) keeps those structural characters so a complete URL stays a working link; it only fixes spaces, quotes and non-ASCII.
Why is a space encoded as %20 and not +?
%20 is the percent-encoding defined by RFC 3986 and works everywhere in a URL. The + form comes from the application/x-www-form-urlencoded format used by HTML forms and is only interpreted as a space in query strings. Both JavaScript functions produce %20.
Why does decoding fail with Invalid percent-encoding?
A % that is not followed by two hex digits, or a byte sequence that is not valid UTF-8 (for example a truncated %E2%82), makes decodeURIComponent throw. Check for a stray % — if you need a literal percent sign it must be written %25.
How are non-ASCII characters like ü or 日本 encoded?
They are converted to UTF-8 bytes first and each byte becomes %XX, so ü becomes %C3%BC and 日 becomes %E6%97%A5. Decoding reverses it, as long as the bytes form valid UTF-8.
Does encodeURIComponent escape everything?
Not quite — it leaves - _ . ! ~ * ' ( ) alone. The characters ! ' ( ) * are reserved by RFC 3986, so if a strict server rejects them, replace them manually with %21 %27 %28 %29 %2A.
Why did my URL break when I encoded it twice?
Encoding an already-encoded string turns every % into %25, so %20 becomes %2520 and the server sees a literal %20 instead of a space. Encode each value exactly once, at the moment you build the URL.