Which characters get encoded
Letters, digits and - _ . ~ are never encoded. Everything else depends on where the text goes:
| Character | Component | Full URL | Form |
|---|---|---|---|
space |
%20 |
%20 |
+ |
! |
%21 |
! |
%21 |
# |
%23 |
# |
%23 |
$ |
%24 |
$ |
%24 |
% |
%25 |
%25 |
%25 |
& |
%26 |
& |
%26 |
' |
%27 |
' |
%27 |
( |
%28 |
( |
%28 |
) |
%29 |
) |
%29 |
* |
%2A |
* |
* |
+ |
%2B |
+ |
%2B |
, |
%2C |
, |
%2C |
/ |
%2F |
/ |
%2F |
: |
%3A |
: |
%3A |
; |
%3B |
; |
%3B |
= |
%3D |
= |
%3D |
? |
%3F |
? |
%3F |
@ |
%40 |
@ |
%40 |
[ |
%5B |
%5B |
%5B |
] |
%5D |
%5D |
%5D |
é |
%C3%A9 |
%C3%A9 |
%C3%A9 |
€ |
%E2%82%AC |
%E2%82%AC |
%E2%82%AC |
The Component column follows RFC 3986 strictly and also encodes ! ' ( ) *, which
JavaScript’s encodeURIComponent leaves alone. Both forms decode to the same text.
URL encoding in code
encodeURIComponent('café & bar'); // 'caf%C3%A9%20%26%20bar'
decodeURIComponent('caf%C3%A9'); // 'café'
// Building query strings: URLSearchParams encodes for you (spaces become +)
const params = new URLSearchParams({ q: 'café & bar', page: '2' });
`https://example.com/search?${params}`; // ...?q=caf%C3%A9+%26+bar&page=2
from urllib.parse import quote, unquote, urlencode
quote("café & bar", safe="") # 'caf%C3%A9%20%26%20bar'
unquote("caf%C3%A9") # 'café'
urlencode({"q": "café & bar"}) # 'q=caf%C3%A9+%26+bar'
# --data-urlencode encodes the value for you
curl -G https://example.com/search --data-urlencode 'q=café & bar'
Python’s quote leaves / unencoded unless you pass safe="", which is a common
cause of broken redirect URLs. For binary data in URLs, consider URL-safe Base64.
To edit a whole URL instead, with parameters you can add, remove and reorder, use the URL Parser.
Frequently asked questions
What is URL encoding?
URL encoding, or percent-encoding, replaces characters that are not allowed or have a special meaning in a URL with % followed by two hex digits of each UTF-8 byte. A space becomes %20, & becomes %26 and é becomes %C3%A9.
Should a space be %20 or +?
Both are common. %20 is the standard percent-encoding and works everywhere in a URL. + means a space only in query strings using the HTML form format (application/x-www-form-urlencoded). In a path, + is a literal plus sign. When unsure, use %20.
What is the difference between encodeURI and encodeURIComponent?
encodeURI encodes a complete URL and leaves characters with structural meaning (: / ? # & =) alone. encodeURIComponent encodes everything except letters, digits and - _ . ! ~ * ' ( ), so it is the right choice for a single query value or path segment. Using encodeURI on a value lets & and = break the query string.
Why does my URL contain %2520?
It was encoded twice. A space became %20, then the % itself was encoded as %25, giving %2520. Decode with “Decode repeatedly” turned on to get the original text, and fix the code that encodes an already-encoded value.
What does “URI malformed” mean?
decodeURIComponent throws URIError: URI malformed when a % is not followed by two hex digits (like 100%) or when the bytes don’t form valid UTF-8 (like %C3 on its own). This tool shows the exact position of the bad sequence. A literal % must be encoded as %25.