URL Encoding Special Characters Guide
URLs can only contain a limited set of ASCII characters — letters, digits, and a few reserved punctuation marks. Everything else must be percent-encoded: replaced by a % sign followed by two hexadecimal digits. Knowing which characters require encoding and when is essential for building correct links, query strings, and API requests.
Characters That Require Encoding
Reserved Characters
Reserved characters have special meaning in URL syntax. When they appear as data (not as delimiters), they must be encoded.
| Character | Encoded | Purpose in URL Syntax |
|---|---|---|
& | %26 | Query parameter separator |
= | %3D | Key-value assignment |
? | %3F | Query string start |
# | %23 | Fragment identifier |
/ | %2F | Path separator |
: | %3A | Scheme/port separator |
; | %3B | Parameter separator |
@ | %40 | Authority delimiter |
+ | %2B | Space (form encoding) |
% | %25 | Encoding prefix itself |
Unsafe and Non-ASCII Characters
Characters that have no defined role in URLs, or that may be modified by transport layers, should always be encoded.
| Character | Encoded | Reason |
|---|---|---|
| Space | %20 or + | Not allowed in URLs |
< | %3C | HTML injection risk |
> | %3E | HTML injection risk |
" | %22 | Delimiter in HTML attributes |
{ } | %7B %7D | Unsafe, often filtered |
\ | %5C | Path manipulation risk |
| ` | ` | %7C |
é | %C3%A9 | Non-ASCII (UTF-8 encoded) |
中 | %E4%B8%AD | Non-ASCII (UTF-8 encoded) |
Space Encoding: %20 vs +
Spaces in URLs have two encodings, and the difference matters:
%20— The standard percent-encoding defined by RFC 3986. Used in path segments and any part of the URL.+— Defined by theapplication/x-www-form-urlencodedmedia type (HTML form submissions). Only valid in query strings.
// Correct: encode path spaces as %20
const path = '/files/my%20document.pdf';
// Correct: encode query spaces as + (form-style) or %20
const query = 'name=John+Doe';
const query2 = 'name=John%20Doe'; // Also valid in query strings
Mixing these up causes bugs. Decoding my+document.pdf as a path produces my+document.pdf (the + is literal), while decoding it as form data produces my document.pdf. Always use %20 for paths and either form for queries, but decode consistently.
Unicode Encoding
Non-ASCII characters are encoded as their UTF-8 byte sequence, with each byte percent-encoded:
Character: é
Unicode: U+00E9
UTF-8: 0xC3 0xA9
Encoded: %C3%A9
Character: 中
Unicode: U+4E2D
UTF-8: 0xE4 0xB8 0xAD
Encoded: %E4%B8%AD
Character: 😊
Unicode: U+1F60A
UTF-8: 0xF0 0x9F 0x98 0x8A
Encoded: %F0%9F%98%8A
Modern browsers display Unicode characters in the address bar for readability, but the underlying bytes are always percent-encoded. You can verify this by copying a URL with non-ASCII characters and pasting it into a plain text editor.
Common Pitfalls
Double Encoding
Encoding an already-encoded string produces double-encoded output that breaks the URL:
const query = 'a=b&c=d';
const encoded = encodeURIComponent(query); // a%3Db%26c%3Dd
const doubleEncoded = encodeURIComponent(encoded); // a%253Db%2526c%253Dd
// Decoding double-encoded string: a%3Db%26c%3Dd (still encoded!)
Never encode a full URL with encodeURIComponent. It encodes the :, /, and ? that are part of the URL structure. Use it only on individual parameter values.
Ampersand in Parameter Values
An unencoded & in a query parameter value truncates the value:
Wrong: ?redirect=https://example.com?a=1&b=2
→ redirect = "https://example.com?a=1", b = "2" (separate param)
Right: ?redirect=https%3A%2F%2Fexample.com%3Fa%3D1%26b%3D2
→ redirect = "https://example.com?a=1&b=2"
Slash Encoding in Paths
Some web frameworks decode %2F in path segments, while others treat it as a literal %2F. This causes routing discrepancies:
/files/path%2Fto%2Ffile → May route to /files/path/to/file OR /files/path%2Fto%2Ffile
If slashes in a path parameter are meaningful data, test your framework's behavior explicitly.
Key Takeaways
- Reserved characters (
&,=,?,#,/) must be encoded when used as data, not delimiters. - Use
%20for spaces in paths;+is only valid in form-encoded query strings. - Unicode characters are percent-encoded as their UTF-8 byte sequences.
- Never
encodeURIComponenta full URL — only encode individual query values. - Double encoding is a common source of broken links; always encode exactly once.
Try It Yourself
Need to encode or decode a URL? Paste it into the URL Encoder to see each component properly percent-encoded, or decode an encoded URL to inspect its original form.