Percent-Encoding Special Characters — A Reference Guide
Bookmark this as your quick lookup for percent-encoding the special characters you'll actually run into — spaces, symbols in query strings, and non-ASCII text. Every value below matches what JavaScript's encodeURIComponent produces.
How percent-encoding works
Each unsafe byte is replaced with % followed by its two-digit hexadecimal value. Multi-byte UTF-8 characters (like emoji or Indian scripts) get encoded as multiple consecutive %XX sequences, one per byte.
' ' → 0x20 → %20 '&' → 0x26 → %26 'नमस्ते' → multi-byte UTF-8 → %E0%A4%A8%E0%A4%AE%E0%A4%B8%E0%A5%8D%E0%A4%A4%E0%A5%87
Common special character reference table
- Space ( ) →
%20(or+in form-urlencoded data) - & →
%26— must encode to avoid splitting query params - = →
%3D— must encode inside a value to avoid ending the key early - ? →
%3F— must encode when it's literal data, not the query start - # →
%23— must encode to avoid being read as a fragment identifier - / →
%2F— encode when it's part of a value, not a path separator - : →
%3A - + →
%2B— important: a literal+must be encoded, or it may be misread as a space - % →
%25— the percent sign itself must be encoded first to avoid double-decoding bugs - @ →
%40 - , →
%2C - ; →
%3B
JavaScript examples for each
encodeURIComponent('hello world'); // 'hello%20world'
encodeURIComponent('salt & pepper'); // 'salt%20%26%20pepper'
encodeURIComponent('a=b'); // 'a%3Db'
encodeURIComponent('is this real?'); // 'is%20this%20real%3F'
encodeURIComponent('section#intro'); // 'section%23intro'
encodeURIComponent('path/to/file'); // 'path%2Fto%2Ffile'
encodeURIComponent('9:30 AM'); // '9%3A30%20AM'
encodeURIComponent('2 + 2 = 4'); // '2%20%2B%202%20%3D%204'
encodeURIComponent('100% sure'); // '100%25%20sure'
encodeURIComponent('user@example.com'); // 'user%40example.com'The space vs plus (+) gotcha
There are two valid encodings for a space, and mixing them up causes bugs. encodeURIComponent always produces %20. But the older application/x-www-form-urlencoded format (used by HTML form submissions and some legacy APIs) encodes a space as + instead — and in that same format, a literal + must itself be encoded as %2B to avoid being misinterpreted as a space.
// URLSearchParams uses the form-urlencoded convention: space → '+'
const params = new URLSearchParams({ q: 'red car' });
params.toString();
// → 'q=red+car' (not 'q=red%20car')
// decodeURIComponent does NOT turn '+' back into a space — use
// URLSearchParams.get() instead, which handles this convention correctly
new URLSearchParams('q=red+car').get('q');
// → 'red car'Characters that never need encoding
Letters, digits, and - _ . ! ~ * ' ( ) are left untouched by encodeURIComponent — encoding them is unnecessary and, if applied twice, causes double-encoding bugs (%20 becoming %2520).
Frequently Asked Questions
A space is encoded as %20 using encodeURIComponent or standard percent-encoding. In application/x-www-form-urlencoded form data specifically, a space may also be encoded as a + character instead.
& is the delimiter that separates key-value pairs in a query string. If a parameter value contains a literal & and it is not encoded to %26, the URL parser will incorrectly split it into a new parameter, corrupting the query string.
Use encodeURIComponent(str) for individual values like query parameters — it encodes every reserved character. Use encodeURI(str) only for a full URL where you want to preserve structural characters like : / ? & =.