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
Secure Password Reset Tokens — Expiry, Storage, and What Most Implementations Get Wrong
A practical guide to building secure password reset flows: token generation, expiry windows, one-time use enforcement, and the edge cases that cause real account takeovers.
Mar 30, 2026 · 7 min readIncident Response for Developers: What to Do When You Get Hacked
A practical incident response guide for developers covering detection, containment, eradication, recovery, and communication when a security breach happens.
Mar 29, 2026 · 9 min readPhishing Prevention: A Developer's Guide to SPF, DKIM, and DMARC
Understand how email spoofing enables phishing attacks and how to implement SPF, DKIM, and DMARC to protect your domain from being impersonated.
Mar 29, 2026 · 9 min read