URL Encoding Explained: %20, + and How to Encode or Decode URLs
Last updated November 2, 2026
URLs can only contain a limited set of characters. Everything else (spaces, accented letters, emoji, and symbols such as & or = inside a value) must be percent-encoded: each byte is written as % followed by two hexadecimal digits. This guide explains the rules, the space problem, and how to encode and decode correctly.
How percent-encoding works
Characters are first converted to UTF-8 bytes, then each byte that is not allowed becomes %XX. A space is %20, & is %26, = is %3D, / is %2F, and รฉ, which is two bytes in UTF-8, becomes %C3%A9.
Letters, digits and - _ . ~ never need encoding. Characters such as ? & = / # : have special jobs in a URL, so they must be encoded when they are part of a value rather than the structure.
Space: %20 or +?
Both are correct in different places:
%20is the general URL encoding and is always safe, including in paths:/files/my%20report.pdf.+means a space only in query strings and HTML form data (application/x-www-form-urlencoded):?q=red+shoes. In a path,+is a literal plus sign.
When in doubt, use %20. When decoding form data, treat + as a space.
Encode a value, not the whole URL
Encode each query value separately, then build the URL. Encoding a complete URL also encodes its ://, ? and &, breaking it. Example: searching for a b&c=d/รฉ should give ?q=a%20b%26c%3Dd%2F%C3%A9 (or a+bโฆ in form style). Left unencoded, the & would start a new parameter.
Double encoding
Encoding something that is already encoded turns % into %25: a%20b becomes a%2520b. If you see %25 followed by two hex digits in a URL, it was probably encoded twice. Decode once, check the result, and encode only at the point where the URL is built.
Encode or decode online
- URL Encoder uses form-style encoding: spaces become
+and every reserved character, including! ' ( ) * ~, is percent-encoded, matching PHP'surlencode. Replace+with%20if you need a path segment. - URL Decoder turns
+back into spaces and decodes%XXsequences. A broken sequence such as100%is left as it is instead of causing an error.
Both run in your browser.
In code
| Language | Encode a value | Decode |
|---|---|---|
| JavaScript | encodeURIComponent(v) (space โ %20) | decodeURIComponent(s) |
| JavaScript, whole query | new URLSearchParams({q: v}).toString() (space โ +) | new URLSearchParams(s).get('q') |
| Python | urllib.parse.quote(v, safe='') or quote_plus(v) | unquote(s) or unquote_plus(s) |
| PHP | rawurlencode($v) (%20) or urlencode($v) (+) | rawurldecode / urldecode |
In JavaScript, encodeURI() is for complete URLs and leaves & = ? / alone, so do not use it for single values.
FAQ
Why does my URL show %20?
It is an encoded space. Browsers often show the decoded version in the address bar but send %20.
Do I need to encode non-English characters?
Yes, in the actual request. Browsers do it automatically for typed addresses, but code that builds URLs must encode them.
Is URL encoding the same as Base64?
No. Percent-encoding only escapes unsafe characters; Base64 rewrites all data. See Base64 explained.
More developer tools are on the developer tools page.
Encode URLs and query text.