encodeURIComponent vs encodeURI: Which One to Use and When
Two JavaScript functions encode a URL, and choosing the wrong one is a persistent source of bugs. encodeURIComponent and encodeURI differ in a single respect: which characters they treat as data versus structure. encodeURIComponent assumes it is handed one piece of a URL, so it escapes almost everything, including the delimiters /, ?, #, &, =, +, and @1. encodeURI assumes it is handed a whole URL, so it preserves those delimiters and encodes only characters that are never legal anywhere, like a space2. Consequently, the right function depends entirely on whether you hold a component or a complete address. Pick encodeURIComponent for a single value, and encodeURI for a finished URL. The CapyToolkit encoder shows both outputs alongside form encoding, so you can watch a single input diverge across all three and confirm your choice before you ship it.
The exact characters each function leaves alone
The precise difference lives in two character sets, and knowing them ends the guesswork. encodeURIComponent leaves unescaped only the unreserved characters: the letters A to Z and a to z, the digits 0 to 9, and the marks - _ . ! ~ * ' ( )1. Everything else becomes a percent-escape.
What encodeURI additionally preserves
encodeURI keeps that same unreserved set and, on top of it, preserves the characters that structure a URL: ; , / ? : @ & = + $ and #3. In other words, encodeURI refuses to touch the delimiters that hold a URL together, which is exactly what you want for a complete address and exactly what you do not want for a lone value. Because the two sets differ only by those delimiters, the practical rule collapses to one question: does the string contain delimiters that are data, or delimiters that are structure? The CapyToolkit ENCODE panel answers it visually for any input you paste.
Thinking in terms of data-versus-structure removes the need to memorize both character sets. If the string is going to become part of a larger URL, it should not contain raw delimiters, so encodeURIComponent is the safer choice. If it is already a complete URL, those characters are doing their job and should stay unescaped, which is what encodeURI gives you.
When to reach for each function
The decision rule is short once you frame it around structure. Reach for encodeURIComponent whenever you assemble a URL from parts: each query value, each path segment, each fragment you build separately. Try round-tripping a query value's ampersand and equals sign to confirm both characters come back escaped instead of splitting the query. Because it escapes delimiters, it guarantees that an & or = inside a value cannot break the query that contains it.
Reach for encodeURI only when you already hold a complete, correct URL and need to make it safe for a context like an HTML href, where a raw space would break the markup. Furthermore, never run encodeURI on a value you are about to insert into a query, and never run encodeURIComponent on a whole URL, since it destroys the :// and every slash4. When you are unsure which you hold, encode the parts rather than the whole, because encoding a value that turns out to be safe is harmless while under-encoding a delimiter is not. Keeping this asymmetry in mind is a useful default whenever you inherit code that mixes the two functions without a clear pattern.
The part-versus-whole rule in practice
The distinction between a component and a whole URL is what makes this feel harder than it is. A query value is a component, so it gets encodeURIComponent. A path segment is a component, so it gets encodeURIComponent. A complete address destined for an href attribute is a whole URL, so it gets encodeURI. Once each value is already encoded, both functions become safe to use in their proper domain, and the distinction can only matter in the step where values are still raw. This is why template strings and API wrappers usually apply encodeURIComponent at the point of insertion rather than on the assembled result: by encoding the parts, you sidestep the entire question of whether the final string is a component or a whole URL.
The bugs that come from the wrong choice
The wrong choice fails in two mirror-image ways. Use encodeURI on a value and its delimiters slip through: an & in Fish & Chips splits the parameter, an = shifts the key-value boundary, and a # truncates everything after it2. The URL looks fine and parses fine, just into the wrong shape.
Reading the symptom to find the mistake
Conversely, use encodeURIComponent on a full URL and it over-encodes: https://example.com/a becomes https%3A%2F%2Fexample.com%2Fa, a string no server can route4. Consequently, the symptom tells you the mistake. Missing structure means you under-encoded a value with encodeURI; a mangled scheme means you over-encoded a URL with encodeURIComponent. Paste any suspect string into the CapyToolkit decoder and the parameter table or decoded output shows which of the two failures you are looking at. Learning to read the symptom this way turns a confusing bug report into a five-second diagnosis instead of a guessing game across the codebase.
When to use this
Use this comparison whenever you build URLs in JavaScript or debug a link that parses into the wrong parameters. Choose encodeURIComponent for single query values, path segments, and fragments; choose encodeURI for a complete URL you only need to make attribute-safe. When a URL misbehaves, the CapyToolkit ENCODE and DECODE panels let you reproduce both functions on your exact input and see which one produces the string you expected.
Examples
Encoding a query value
Fish & Chips
Fish%20%26%20Chips
encodeURIComponent escapes the ampersand so it cannot split the parameter.
Encoding a full URL for an href
https://example.com/search?q=cat photos
https://example.com/search?q=cat%20photos
encodeURI encodes the space but preserves ://, ?, and =.
The over-encoding mistake
https://example.com/a?b=c
https%3A%2F%2Fexample.com%2Fa%3Fb%3Dc
Running encodeURIComponent on a whole URL destroys its structure, so no server can route it.
The under-encoding mistake
name=A&B Corp
name=A&B Corp
encodeURI leaves the ampersand, so B Corp is read as a second, empty parameter.
- 1.
Mozilla Developer Network, "encodeURIComponent()," developer.mozilla.org, accessed July 2026. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
- 2.
Mozilla Developer Network, "encodeURI()," developer.mozilla.org, accessed July 2026. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
- 3.
IETF, "Uniform Resource Identifier (URI): Generic Syntax," RFC 3986, datatracker.ietf.org, January 2005. https://datatracker.ietf.org/doc/html/rfc3986
- 4.
Ecma International, "ECMAScript 2026 Language Specification," ecma-international.org, June 2026. https://tc39.es/ecma262/#sec-encodeuri-uri