URL encoder
Percent-encoding replaces characters that would otherwise mean something in a URL. Component encoding and form-body encoding differ by more than a space: a form body also escapes characters encodeURIComponent leaves alone. This page shows those two plus encodeURI for a complete URL, rather than making you guess which one you have.
Paste a string and you see, side by side, what it becomes under all three: encodeURI, encodeURIComponent and application/x-www-form-urlencoded. The notes below say which one to use for a query value, a path segment, a fragment, a form body or a complete URL.
Encode or decode
Result
Decoded something larger? Send it to the tool chain to keep going.
- In / out
- ·
- Escaped
- ·
- Direction
- ·
- Network requests
- ·
- Our own script
- ·
Marked helpful 2 times.
Was this tool useful?
The same string, three encodings
Take hello world/foo?x=1. Component encoding is
hello%20world%2Ffoo%3Fx%3D1, because a space, a slash, a question
mark, and an equals sign would otherwise be URL syntax. Form-body encoding is
hello+world%2Ffoo%3Fx%3D1: the same reserved characters, but a
space becomes a plus. encodeURI for a complete URL is
hello%20world/foo?x=1, because it leaves the delimiters in place.
Paste that string here and the three rows should match those three strings.
Which encoding, by destination
A query value and a path segment want component encoding, where a space is
%20. A form body wants
application/x-www-form-urlencoded, where a space is
+. A fragment is a component too. A complete URL that already
has its delimiters in place wants encodeURI, which leaves
: / ? # & = alone so the URL keeps working.
The plus sign and the space
There are two percent-encodings in daily use, and they differ by more than the space. On ~_.-!*() a, component encoding is
~_.-!*()%20a and form encoding is %7E_.-%21*%28%29+a.
They differ for ~, !, (, ) and
the space.
Component encoding is what encodeURIComponent produces.
A space becomes %20. RFC 3986 section 2.3 names letters, digits,
-, ., _ and ~ as unreserved;
encodeURIComponent also leaves !, *,
(, ) and ' literal, which that unreserved set
does not. Use it for a single value going into a path segment, a query value or a
fragment.
Form encoding is the
application/x-www-form-urlencoded serializer, which is what an HTML form
posts and what most server frameworks assume when they parse a query string. A space
becomes +.
Encode one way, decode the other, and a space turns into a literal plus or a genuine
plus turns into a space. That second one is the expensive version: a plus in an email
address, a signature or a base64 string is meaningful, and turning it into a space
corrupts the value rather than merely looking odd. The decode result row is
decodeURIComponent, the widest of the three going backwards, and Copy
first result copies that row. In decode mode the row carries no encoding name, because decoding is not an encoding. Raising the pass count changes how many times decode runs, not that label. If the input contains a
plus, both readings are printed beside it, labeled form data and RFC 3986, and neither
of those labels is marked as chosen.
The third one, and when not to use it
encodeURI is for a complete URL, and it deliberately leaves
: / ? # & = alone so the URL keeps working. That makes it exactly
wrong for encoding one value: a value containing an ampersand or an equals sign will
pass through untouched and then be read as a parameter boundary by the receiving
server.
It is shown here because it is genuinely the right answer when the whole thing you are holding is a URL with a space in it. The label beside that row does not name a standard character set, because encodeURI does not match any single one exactly.
Hosts are not percent-encoding
A non-ASCII host is IDNA-encoded, not percent-encoded. Mixing the two is how a host gets percent-encoded when it should not. When the input parses as a URL, the parts table shows the host in the IDNA form the WHATWG parser produces, and says so beside that cell. The three encode rows still percent-encode the whole string, including the host, because that is what those three functions do.
Decoding a string that was encoded twice
When the decoded result is itself a URL, this breaks it into scheme, userinfo, host, port, path, query and fragment. Recursive decode sets a ceiling of 1 to 16 passes and then reports how many passes actually changed the string. If the input already contains a percent-escape, decode mode says so before you have to notice leftover percent signs.
One thing the parts table quietly demonstrates: the fragment, the piece after the
#, is the only part of a URL a browser never sends to a server. That is
why every tool on this site puts shareable state there.
What this deliberately does not do
It does not wrap output into 76-character lines. That wrapping is an RFC 2045 MIME convention, and a wrapped percent-encoded URL is not a URL. It does not take a file; per-line encode and decode cover the bulk job. It does not convert a host to punycode on its own, and it does not do base64 or hex. For base64, use the base64 page.
All three rows encode text as UTF-8, and there is no charset control. So é becomes %C3%A9, its two UTF-8 bytes. An older server that expects ISO-8859-1 would want %E9 instead, and this page cannot produce that.
Questions
What is URL encoding?
It's also called percent-encoding. A character that would mean something in a URL, or that isn't allowed there, becomes a % and two hex digits for each of its UTF-8 bytes. A space becomes %20 and a slash becomes %2F. Paste text here and you'll see all three versions at once: encodeURI, encodeURIComponent and form encoding.
How do you encode a space in a URL?
As %20 in a path or a query value. That's what the encodeURIComponent row shows. As + in a form body, the application/x-www-form-urlencoded row. Decode with the wrong one and a real plus turns into a space. When your input holds a +, decode mode prints both readings, so you can pick the one that fits.
What do %40, %27 and %20 mean?
%40 is @, %27 is an apostrophe and %20 is a space. Encoding doesn't always produce them, though. encodeURIComponent leaves an apostrophe as it is, and only the form row turns it into %27. Encode "it's me@x" and the component row gives it's%20me%40x, while the form row gives it%27s+me%40x.
How do I encode a slash, an ampersand or an equals sign?
Read the encodeURIComponent row. A slash becomes %2F, an ampersand %26 and an equals sign %3D. Going the other way, %2F decodes to a slash and %3D to an equals sign. Skip the encodeURI row for a single value. It leaves /, & and = untouched, so the server reads them as URL structure. Copy first result copies the encodeURIComponent row in encode mode.
Why does my decoded string still have percent signs in it?
It was probably encoded twice. That happens when a URL gets put inside another URL as a parameter. Raise Recursive decode passes, up to 16, and decode again. The page tells you how many passes changed the string. %252F takes two: the first gives %2F, and the second gives /.
Is my URL uploaded?
No. Encoding and decoding both happen in this tab. That matters here, since URLs often carry session tokens and API keys, and people paste them in without a second thought. Once the page has loaded, you can switch off your network and it keeps working.
Related tools
For = padding rather than % escapes, you want
base64. If the decoded value turns out to be JSON, the
JSON formatter will indent it and locate any syntax
error, and the tool chain will do both steps on one paste.