Which Characters Need to Be Encoded in a URL?
URLs can only contain specific ASCII characters defined in RFC 3986. All other characters must be percent-encoded: replaced by % followed by the two-digit hex value of their UTF-8 byte. Characters that are always safe (never encoded): AāZ, aāz, 0ā9, and the 'unreserved' symbols - _ . ~ Characters that are 'reserved' (structural meaning in URLs): : / ? # [ ] @ ! $ & ' ( ) * + , ; = Whether to encode these depends on context ā inside a query value, & must be encoded as %26 or the parser splits the parameter. In the full URL structure, & is a parameter separator and should stay as-is. Common percent-encoded values: ⢠Space ā %20 (or + in form-urlencoded) ⢠& ā %26 ⢠= ā %3D ⢠# ā %23 ⢠+ ā %2B ⢠/ ā %2F
encodeURIComponent vs encodeURI: The Difference
encodeURIComponent(str): encodes everything except unreserved characters (AāZ, aāz, 0ā9, - _ . ~). This includes all reserved characters like : / ? # & =. Use this for encoding individual query parameter values. encodeURI(str): encodes everything except unreserved characters AND reserved characters. It leaves : / ? # [ ] @ ! $ & ' ( ) * + , ; = intact. Use this for encoding a complete URL where you want to preserve the URL structure. Example: const title = 'Hello & World / 2025'; console.log(encodeURIComponent(title)); // 'Hello%20%26%20World%20%2F%202025' console.log(encodeURI(title)); // 'Hello%20&%20World%20/%202025' For a query parameter: https://example.com/search?q=' + encodeURIComponent(title) ā https://example.com/search?q=Hello%20%26%20World%20%2F%202025 ā If you use encodeURI instead: https://example.com/search?q=' + encodeURI(title) ā https://example.com/search?q=Hello%20&%20World%20/%202025 ā The & breaks the query string into two parameters: q=Hello%20 and %20World%20/%202025
Form-Urlencoded: The Third Encoding Method
HTML form submissions with method='POST' and enctype='application/x-www-form-urlencoded' (the default) use a third encoding variant: ⢠Spaces are encoded as + instead of %20 ⢠All other special characters use standard percent-encoding This is why you see + in URL query strings from older HTML forms. Modern fetch() and axios requests using JSON bodies do not use form encoding ā only traditional form submissions and some legacy APIs. To decode + back to spaces on the server side, use decodeURIComponent on the value (which only handles %20) before splitting, or use a form body parser that handles the + conversion automatically. The ToolMint URL Encoder/Decoder supports all three methods so you can test the exact encoding your form or API will produce.
Practical Rules: Which Method to Use When
Encoding a query parameter value (user input, search terms, file names): use encodeURIComponent ⢠const url = '/search?q=' + encodeURIComponent(userQuery); Encoding a full URL you received from somewhere else (to pass it as a parameter): use encodeURIComponent ⢠const link = '/redirect?to=' + encodeURIComponent(fullUrl); Constructing a URL from trusted parts (known protocol, host, path): use encodeURI or template literals ⢠const url = encodeURI('https://example.com/path with spaces/page'); Encoding form data for a POST body: use URLSearchParams ā it handles encoding automatically ⢠const body = new URLSearchParams({key: value}); // produces correct form-urlencoded output Decoding a URL from user input or an API response: use decodeURIComponent ā it handles %20, %26, %2F, and all other percent sequences.