You've got a search API. A user types hello & goodbye = forever. You blindly interpolate that into a query string, ship it, and six months later someone files a bug because & splits the parameter in half and the backend gets two garbage keys instead of one. You've seen this. Everyone has seen this.
The fix is one function call. But which one?
What Each Function Actually Encodes
The difference comes down to which characters get percent-encoded.
encodeURI leaves these characters alone because they're structurally meaningful in a URL:
; , / ? : @ & = + $ # A-Z a-z 0-9 - _ . ! ~ * ' ( )
encodeURIComponent encodes everything except unreserved characters:
A-Z a-z 0-9 - _ . ! ~ * ' ( )
That means encodeURIComponent will encode : / ? # @ & = + , $ — all the characters that give a URL its shape.
Live comparison — type anything or try a sample
✓ For query params and user input: always use encodeURIComponent
Use encodeURI only for complete, already-assembled URLs with no user data
Concrete example:
The Production Bug encodeURI Creates
Say you're building a redirect URL with a returnTo parameter:
/login?returnTo=https://app.example.com/dashboard?tab=settings&user=42
If you use encodeURI on the returnTo value, the ?, =, and & in the value are left unencoded. Your server now sees:
returnTo = https://app.example.com/dashboard
tab = settings
user = 42
Three parameters instead of one. The login redirect breaks, and in a worst case where you're using that returnTo value without validation, you've got an open redirect vulnerability.
encodeURIComponent would have produced:
/login?returnTo=https%3A%2F%2Fapp.example.com%2Fdashboard%3Ftab%3Dsettings%26user%3D42
One parameter. Correct.
When encodeURI Is Actually the Right Call
Almost never — but there is a valid use case: you've received a URL string that might contain non-ASCII characters and you need to normalize it without destroying its structure.
const messyURL = "https://example.com/résumé?lang=fr";
encodeURI(messyURL);
// "https://example.com/r%C3%A9sum%C3%A9?lang=fr"The path gets fixed, the ? and = stay intact. This is a narrow, specific use case — not the default.
The Gotcha Junior Devs Miss: + vs %20
encodeURIComponent encodes spaces as %20. Some server-side parsers (especially older PHP and Java URLDecoder) expect + for spaces in query strings, not %20. They're both valid in different contexts:
%20— RFC 3986 (URI spec), correct for path segments and modern query parsers+— HTML form encoding (application/x-www-form-urlencoded), used byURLEncoder.encode()in Java andurlencode()in PHP
If you're building a query string to submit as a form, + for spaces is fine. If you're constructing a URL programmatically to pass to a fetch/HTTP client, use %20 via encodeURIComponent.
Mixing them up causes intermittent decoding bugs that only appear with user input containing spaces — the kind that pass your own tests but blow up in production.
Building Full URLs Safely
Don't manually concatenate URLs. Use the URL constructor or your language's URI builder:
URLSearchParams, URLComponents, URIBuilder, http_build_query — they all call the equivalent of encodeURIComponent under the hood. Let them do the work.
Use encodeURIComponent (or your language's equivalent) any time you're embedding a value inside a URL — query params, path segments, fragment identifiers. Use encodeURI only when you have a fully-formed URL that needs non-ASCII normalization, which is rare.
The URL API in every modern language handles encoding correctly when you build URLs through it rather than string interpolation. That's the real answer: stop manually constructing URLs, and the encodeURI vs encodeURIComponent question mostly goes away.
Frequently Asked Questions
Related posts
Prompt Injection: Why You Can't Fix It With a Better Prompt
Prompt injection isn't a filtering problem you can prompt your way out of. It's an architecture problem — the model can't tell your instructions from the data it's reading. Here's what actually contains it.
Jul 28, 2026 · 11 min readPhishing URLs: How Attackers Fake Domains (and How to Read Them)
Typosquatting, homograph attacks, subdomain deception, and the @ trick — learn the handful of URL tricks behind most phishing, and the one habit that beats all of them.
Jun 13, 2026 · 7 min readWhat Is CSV Injection — and How to Stop It in Your Export Feature
CSV (formula) injection turns a harmless 'export to spreadsheet' button into code execution on whoever opens the file. Here's how the attack works and how to prevent it.
Jun 13, 2026 · 7 min read