Ever pasted a URL with spaces, Chinese characters, or an emoji into an API call and watched it explode with a 400 error? That's URL encoding — or the lack of it — biting you.
What URL encoding actually is
URLs are restricted to a small set of characters per RFC 3986: A-Z, a-z, 0-9, and a handful of reserved symbols (-, _, ., ~). Everything else — spaces, non-ASCII characters, and the reserved delimiters themselves (/, ?, &, #, %, =) — must be percent-encoded.
Each encoded character becomes a % followed by two hex digits:
| Character | Encoded |
|---|---|
| space | %20 |
/ |
%2F |
? |
%3F |
& |
%26 |
# |
%23 |
你 |
%E4%BD%A0 |
The classic JavaScript bug
encodeURI() encodes everything EXCEPT the reserved characters — which is why it's fine for the URL as a whole but WRONG for query values:
const q = "C# & JavaScript";
fetch(`/search?q=${encodeURI(q)}`); // broken: # and & survive
fetch(`/search?q=${encodeURIComponent(q)}`); // "C%23%20%26%20JavaScript"
When a value contains #, &, or =, those characters change the meaning of the URL if they pass through raw. encodeURIComponent() escapes all of them — use it for every query parameter and path segment you build dynamically.
Decoding matters just as much
You'll hit the reverse problem too: a file literally named my%20file.pdf because someone double-encoded it, or log output showing %E4%BD%A0 where a Chinese word should be. A reliable decoder that handles UTF-8 and edge cases saves real debugging time.
If you ever need to quickly encode or decode a string — or double-check what your code is actually sending — I keep coming back to CodeToolbox URL Encoder. It encodes and decodes in both directions with full UTF-8 support, no uploads, no signup required.
Top comments (0)