What Is URL Encoding?
URL encoding (also called percent-encoding) is the process of rewriting text so it can appear safely
inside a URL. URLs are constrained: they may only contain a small set of ASCII characters — letters,
digits, and a handful of symbols — and even some of those symbols have structural meaning (a /
separates path segments, a ? starts the query string, an & separates
query parameters). Any character outside the safe set must be re-expressed. Percent-encoding does
this by converting the offending bytes to UTF-8 and writing each byte as a % followed by
two hexadecimal digits: a space becomes %20, a = becomes %3D,
and an emoji becomes a run of escapes like %F0%9F%98%80.
The result is always a string of plain ASCII, which is why encoded URLs survive transport through systems that assume plain text — email, logs, older protocols, and databases that predate Unicode. A decoder simply performs the reverse mapping, which is exact: encode and decode are strict inverses, so nothing is ever lost in the round trip.
Why You Need It
- Query parameters with special values: passing a value that contains
&,=,?, or spaces — for example a search term, a redirect URL, or a user-provided string — must be encoded or the server will mis-parse it. - Non-ASCII text in links: emoji, accented letters, and non-Latin scripts (Chinese, Arabic, Cyrillic) cannot appear raw in a URL; browsers percent-encode them, and this tool lets you produce or inspect that form.
- Building links programmatically: composing a URL from parts in a script or a no-code tool where you control each segment and must escape it correctly.
- Debugging: decoding a link that came out of an email, an analytics report, or a log file to see what it actually means.
- Form and API work: understanding and producing the application/x-www-form-urlencoded style payloads used by HTML forms and many APIs, where the same escape rules apply.
The Standard: RFC 3986
This tool implements percent-encoding as defined in
RFC 3986,
the IETF standard for URI syntax. The specification divides characters into two groups. The
unreserved set — letters, digits, and - _ . ~ — is always safe and is never escaped. Everything else is either reserved
(characters like : / ? # & = that have structural roles) or simply unsafe in a URI, and those get percent-escaped
when they appear in a component. Note that the modern standard reserves ! * ' ( ) as
well, but the widely used encodeURIComponent function — which this tool wraps — leaves
them unescaped for compatibility, exactly like the reference behavior on every major platform.
How the Tool Works
The encoder converts the text to UTF-8 bytes and percent-escapes every byte that is not in the
safe set, so emoji and non-Latin scripts encode correctly without any special handling. The decoder
does the reverse, and never throws: if the input contains a malformed escape (a bare %,
a non-hex pair like %zz, or a truncated multi-byte sequence), you get a clear error
message instead of a crash. Because decoding is exact, you can always check your work — paste the
encoded output back into the decoder and you should get exactly the text you started with.
Step-by-Step: What Happens When You Encode
Following one example through the whole pipeline makes the behavior concrete. Take
café 日本 😀. The encoder first converts the text to UTF-8 bytes: the letters
c a f are single bytes, but é is two bytes
(C3 A9), the space is one (20), each Japanese character is three bytes
(E6 97 A5 and E6 9C AC), the second space is one, and the emoji is four
bytes (F0 9F 98 80). Every byte that is not a safe ASCII letter or digit is then
written as a percent-escape, producing caf%C3%A9%20%E6%97%A5%E6%9C%AC%20%F0%9F%98%80.
Decoding walks the string in the opposite direction — each %XX pair becomes one byte,
the bytes are reassembled, and UTF-8 decoding yields exactly the text you started with. Nothing is
approximated or lost in either direction, which is why the round trip is always exact.
Where You'll Meet Percent-Encoding
- Search and filter URLs: links like
?q=hello worldexist all over the web; the space in the query value must be escaped before the URL is valid. - Redirect and callback parameters: OAuth flows pass a
redirect_uriinside the query string, which means the callback URL itself must be encoded as a value — the classic example of a URL nested inside a URL. - API query strings: building a request by concatenating raw user input is how broken parameters happen; encoding each value before joining is the fix.
- HTML forms: the classic form submission body (application/x-www-form-urlencoded) uses the same escape rules, so an encoded value you see in network tools decodes with this same decoder.
- Tracking links and deep links: marketing and mobile links routinely carry encoded payloads, and support teams decode them to see what a link actually contained.
Reference Table
| Plain Text | URL-Encoded |
|---|---|
| hello world | hello%20world |
| a=1&b=2?x | a%3D1%26b%3D2%3Fx |
| café 日本 😀 | caf%C3%A9%20%E6%97%A5%E6%9C%AC%20%F0%9F%98%80 |
| !~*'() | !~*'() |
| https://example.com/path?q=1 | https%3A%2F%2Fexample.com%2Fpath%3Fq%3D1 |
The last row shows component encoding applied to a whole URL — correct for a value embedded inside another URL, but not something you would paste as a link. Paste any row into the tool to confirm, or decode the right-hand values back to the left-hand ones.
Troubleshooting & Practical Tips
Decode Errors Almost Always Mean a Partial Paste
If the decoder reports an invalid escape, the string is usually truncated — a % at the
very end, or a multi-byte character whose last escape was cut off. Paste the complete value and the
error clears.
Don't Double-Encode
Running encoded text through the encoder a second time escapes the % itself
(hello%20world becomes hello%2520world). If you see a value that looks
double-encoded, decode it once more rather than re-encoding it.
Whole URLs vs Components
Encode the individual pieces of a URL — the query value, the path segment — not the whole link. A
readable URL like https://example.com/search?q=hello world only needs its value encoded
(q=hello%20world); encoding the whole thing turns the :// into
%3A%2F%2F and breaks it.