</>
character.codes
← Back to Learn

URL Encoding Explained: When and How to Percent-Encode

Published March 1, 2025

What is percent-encoding?

Percent-encoding (also called URL encoding) is a mechanism for encoding characters in a URI that are not allowed or have special meaning. Each encoded character is represented as a percent sign (%) followed by two hexadecimal digits representing the byte value.

For example, a space becomes %20, and an ampersand becomes %26.

RFC 3986 reserved characters

RFC 3986 defines which characters have special meaning in URIs and must be percent-encoded when used as data (not delimiters):

: / ? # [ ] @ ! $ & ' ( ) * + , ; =

Characters that are unreserved — letters, digits, hyphens, periods, underscores, and tildes — can appear in a URI without encoding.

Common percent-encoded characters

CharacterEncodedASCII Dec
Space%2032
!%2133
#%2335
&%2638
/%2F47
=%3D61
?%3F63

encodeURIComponent vs. encodeURI

JavaScript provides two functions for URL encoding, and they behave differently:

  • encodeURIComponent() — Encodes everything except unreserved characters. Use this for encoding values in query strings or path segments.
    encodeURIComponent("hello world&foo=bar")
    // "hello%20world%26foo%3Dbar"
  • encodeURI() — Encodes a complete URI but preserves characters that have structural meaning (like /, ?, #). Use this for encoding an entire URL.
    encodeURI("https://example.com/path?q=hello world")
    // "https://example.com/path?q=hello%20world"

Common gotchas

  • Double encoding — Encoding an already-encoded string turns %20 into %2520. Always check whether your input has already been encoded.
  • Spaces as + — In HTML form submissions (application/x-www-form-urlencoded), spaces are encoded as + instead of %20. This is a different encoding standard and encodeURIComponent does not produce +.
  • Non-ASCII characters — Characters outside ASCII are first encoded to UTF-8 bytes, then each byte is percent-encoded. The emoji 😀 becomes %F0%9F%98%80 (four UTF-8 bytes).