URL Encoding Cheat Sheet

Unreserved Characters (Never Encoded)

These characters can appear in any part of a URL without encoding (RFC 3986 Β§2.3):

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9
- _ . ~

Everything else must be percent-encoded when used as data in URL components.

Reserved Characters

These have special meaning in URLs and must be encoded when used as data:

CharacterEncodedRole in URL
:%3AScheme separator, port
/%2FPath separator
?%3FQuery string start
#%23Fragment start
[%5BIPv6 address
]%5DIPv6 address
@%40User info separator
!%21Sub-delimiter
$%24Sub-delimiter
&%26Query parameter separator
'%27Sub-delimiter
(%28Sub-delimiter
)%29Sub-delimiter
*%2ASub-delimiter
+%2BSub-delimiter / space in forms
,%2CSub-delimiter
;%3BSub-delimiter
=%3DKey-value separator

Common Percent Encodings

CharacterEncodedNotes
(space)%20Standard encoding
(space)+Form encoding only (application/x-www-form-urlencoded)
%%25The escape character itself
"%22Double quote
<%3CLess than
>%3EGreater than
{%7BLeft brace
}%7DRight brace
|%7CPipe
\%5CBackslash
^%5ECaret
`%60Backtick
(newline)%0ALine feed (LF)
(carriage return)%0DCarriage return (CR)
(tab)%09Horizontal tab

encodeURI vs encodeURIComponent

encodeURI()encodeURIComponent()
PurposeEncode a complete URLEncode a single value
Use forFull URLs with non-ASCII charsQuery param values, path segments
EncodesNon-ASCII + some unsafeEverything except A-Za-z0-9 - _ . ~
Preserves: / ? # [ ] @ ! $ & ' ( ) * + , ; =Nothing (all reserved chars encoded)
Space%20%20

Rule: Use encodeURIComponent() for values. Use encodeURI() only for complete URLs.

// CORRECT β€” encoding a query parameter value
const value = 'price > 100 & category = shoes';
const url = `https://example.com/search?q=${encodeURIComponent(value)}`;
// https://example.com/search?q=price%20%3E%20100%20%26%20category%20%3D%20shoes

// WRONG β€” encodeURIComponent on a full URL breaks it
encodeURIComponent('https://example.com/path?q=hello')
// https%3A%2F%2Fexample.com%2Fpath%3Fq%3Dhello  ← broken!

Encoding by Language

LanguageEncode (RFC 3986)Encode (form)Decode
JavaScriptencodeURIComponent(s)new URLSearchParams({k: s})decodeURIComponent(s)
Pythonurllib.parse.quote(s)urllib.parse.urlencode({k: s})urllib.parse.unquote(s)
PHPrawurlencode($s)urlencode($s)rawurldecode($s)
Gourl.PathEscape(s)url.QueryEscape(s)url.PathUnescape(s)
JavaURI(…).toASCIIString()URLEncoder.encode(s, UTF_8)URLDecoder.decode(s, UTF_8)
RubyERB::Util.url_encode(s)URI.encode_www_form_component(s)URI.decode_www_form_component(s)
C#Uri.EscapeDataString(s)HttpUtility.UrlEncode(s)Uri.UnescapeDataString(s)
Bashjq -sRr @uricurl --data-urlencodepython3 -c "…unquote()"

UTF-8 Multi-Byte Encoding

Non-ASCII characters are first converted to UTF-8 bytes, then each byte is percent-encoded:

CharacterUTF-8 BytesEncoded
Γ© (U+00E9)C3 A9%C3%A9
Γ± (U+00F1)C3 B1%C3%B1
Π” (U+0414)D0 94%D0%94
ζ—₯ (U+65E5)E6 97 A5%E6%97%A5
€ (U+20AC)E2 82 AC%E2%82%AC
πŸš€ (U+1F680)F0 9F 9A 80%F0%9F%9A%80

Space Encoding: %20 vs +

FormatSpace becomesStandardUsed by
Percent-encoding%20RFC 3986Path segments, general URLs
Form encoding+WHATWG URL / HTML formsQuery strings from form submissions

%20 is universally safe. + only works in query strings and may not be decoded correctly in path segments.

Common Mistakes

MistakeProblemFix
Double encoding%20 β†’ %2520Always encode raw values, never pre-encoded
encodeURIComponent on full URLBreaks ://, /, ?Use encodeURI() or URL API for full URLs
encodeURI on a parameter value& and = not encodedUse encodeURIComponent() for values
Forgetting to encode %100% β†’ ambiguous100%25 (encode the percent sign)
+ in path segmentsNot decoded as spaceUse %2B for literal +, %20 for space
Not decoding server-side%C3%A9 shown as textDecode before processing

Tools and Resources

url encoding percent-encoding web reference

Related Tools

More Cheat Sheets