encodeURI vs encodeURIComponent
When to use each JavaScript URL encoding function, with side-by-side examples and common pitfalls to avoid.
The Core Difference
JavaScript provides two built-in functions for URL encoding: encodeURI() andencodeURIComponent(). Both convert characters to their percent-encoded equivalents, but they differ in which characters they encode. Understanding this distinction is essential for building correct URLs in web applications.
The fundamental rule is simple:
encodeURI()encodes a complete URL. It preserves characters that are part of URL syntax (like://,/,?,#, and&) while encoding characters that are not valid in any URL context.encodeURIComponent()encodes a single component of a URL (such as a query parameter value or a path segment). It encodes everything except unreserved characters, including the structural characters thatencodeURI()leaves alone.
What Each Function Encodes
Both functions leave the following unreserved characters unencoded:
A-Z a-z 0-9 - _ . ~The difference lies in how they handle reserved characters:
| Character | encodeURI() | encodeURIComponent() |
|---|---|---|
| : / ? # [ ] @ | Not encoded (preserved) | Encoded |
| ! $ & ' ( ) * + , ; = | Not encoded (preserved) | Encoded |
| Space | Encoded as %20 | Encoded as %20 |
| Non-ASCII (e.g. é, ü) | Encoded | Encoded |
In short, encodeURI() preserves 18 more characters than encodeURIComponent(). Those 18 characters are exactly the ones that serve as structural delimiters in URLs.
Side-by-Side Examples
Seeing both functions applied to the same input makes the difference concrete:
const url = 'https://example.com/path?q=hello world&lang=en#top';
encodeURI(url);
// "https://example.com/path?q=hello%20world&lang=en#top"
// Preserves :// / ? & = #
encodeURIComponent(url);
// "https%3A%2F%2Fexample.com%2Fpath%3Fq%3Dhello%20world%26lang%3Den%23top"
// Encodes EVERYTHING except unreserved charsNotice how encodeURI() keeps the URL structurally intact -- the scheme, path separators, query delimiter, and fragment are all preserved. Meanwhile, encodeURIComponent() treats the entire string as a data value and encodes every special character, making the result unusable as a URL.
When to Use encodeURI()
Use encodeURI() when you have a complete URL string that may contain characters needing encoding, but whose structural components (scheme, host, path separators) should remain intact. Common scenarios include:
// Encoding a URL with spaces in the path
const pageURL = 'https://example.com/my documents/report.pdf';
encodeURI(pageURL);
// "https://example.com/my%20documents/report.pdf"
// Encoding a URL with non-ASCII characters
const intlURL = 'https://example.com/café/menu';
encodeURI(intlURL);
// "https://example.com/caf%C3%A9/menu"
// Setting window.location
window.location.href = encodeURI(userProvidedURL);However, encodeURI() is less common in practice than encodeURIComponent() because most real-world encoding needs involve individual values, not complete URLs.
When to Use encodeURIComponent()
Use encodeURIComponent() when encoding a value that will be embedded within a URL. This is the more commonly needed function. Key scenarios include:
Query Parameter Values
// Building a search URL
const query = 'price > 100 & category = "books"';
const url = `https://api.example.com/search?q=${encodeURIComponent(query)}`;
// "https://api.example.com/search?q=price%20%3E%20100%20%26%20category%20%3D%20%22books%22"
// Without encoding, the & would be interpreted as a parameter separator!Path Segments
// User-generated content in URL paths
const username = 'john/doe';
const url = `https://example.com/users/${encodeURIComponent(username)}`;
// "https://example.com/users/john%2Fdoe"
// Without encoding, this would create an extra path segmentForm Data
// Building application/x-www-form-urlencoded body
const params = new URLSearchParams();
params.set('name', 'Jane & John');
params.set('city', 'San Francisco');
params.toString();
// "name=Jane+%26+John&city=San+Francisco"
// Note: URLSearchParams uses + for spaces (form encoding convention)Encoding URLs as Values
// Passing a URL as a query parameter (e.g., redirect URLs)
const redirectURL = 'https://example.com/callback?token=abc';
const loginURL = `https://auth.example.com/login?redirect=${encodeURIComponent(redirectURL)}`;
// "https://auth.example.com/login?redirect=https%3A%2F%2Fexample.com%2Fcallback%3Ftoken%3Dabc"
// The inner URL's special characters are encoded so they don't
// interfere with the outer URL's structureThe Most Common Mistake
The single most frequent URL encoding bug is using encodeURI() when you should useencodeURIComponent() -- specifically when encoding query parameter values:
// WRONG: encodeURI doesn't encode & in the value
const search = 'Tom & Jerry';
const badURL = `/search?q=${encodeURI(search)}`;
// "/search?q=Tom%20&%20Jerry"
// The server sees TWO parameters: q="Tom " and " Jerry"=""
// CORRECT: encodeURIComponent encodes the &
const goodURL = `/search?q=${encodeURIComponent(search)}`;
// "/search?q=Tom%20%26%20Jerry"
// The server sees ONE parameter: q="Tom & Jerry"This mistake is particularly insidious because it often works in testing with simple inputs. The bug only manifests when the input contains reserved characters like &, =,#, or ?.
Decoding: decodeURI() and decodeURIComponent()
Each encoding function has a corresponding decoding function:
decodeURI()decodes a full URL, leaving structural characters untoucheddecodeURIComponent()decodes a single component, converting all percent-encoded sequences back to characters
const encoded = 'hello%20world%26goodbye';
decodeURI(encoded);
// "hello world%26goodbye" -- & stays encoded (it's a reserved character)
decodeURIComponent(encoded);
// "hello world&goodbye" -- everything is decodedA critical rule: always decode with the function that matches how the string was encoded. Mixing encoding and decoding functions can produce incorrect results or throw URIError exceptions.
The Modern Alternative: URL and URLSearchParams
Modern JavaScript provides the URL and URLSearchParams APIs, which handle encoding automatically and are generally safer than manual encoding:
// Building a URL with URLSearchParams
const url = new URL('https://example.com/search');
url.searchParams.set('q', 'hello world & goodbye');
url.searchParams.set('page', '1');
url.toString();
// "https://example.com/search?q=hello+world+%26+goodbye&page=1"
// Reading query parameters
const params = new URLSearchParams('q=hello+world&page=1');
params.get('q'); // "hello world"
params.get('page'); // "1"The URL API encodes values correctly, handles edge cases like duplicate parameters, and provides a clean object-oriented interface. For new code, prefer URL and URLSearchParams over manual string concatenation with encodeURIComponent().
Equivalents in Other Languages
Every major programming language has analogous functions. Here is a quick reference:
| Language | Like encodeURI | Like encodeURIComponent |
|---|---|---|
| Python | urllib.parse.quote(s, safe='/:?#[]@!$&'()*+,;=') | urllib.parse.quote(s, safe='') |
| Go | url.PathEscape() | url.QueryEscape() |
| PHP | N/A (manual) | rawurlencode() |
| Ruby | URI.encode_www_form_component() (partial) | CGI.escape() |
| Java | N/A (manual) | URLEncoder.encode(s, "UTF-8") |
| C# | Uri.EscapeUriString() | Uri.EscapeDataString() |
Notice that not every language provides a direct equivalent of encodeURI(). In many cases, the language only provides the component-level encoding function, and developers must construct full URLs using builder classes or by encoding individual parts separately.
Quick Decision Guide
When in doubt, use this decision tree:
- Are you encoding a complete URL? Use
encodeURI()or, better yet, theURLconstructor. - Are you encoding a query parameter value? Use
encodeURIComponent()orURLSearchParams.set(). - Are you encoding a path segment? Use
encodeURIComponent(). - Are you encoding form data? Use
URLSearchParams(which handles the+for spaces convention). - Are you unsure? Default to
encodeURIComponent(). It is the safer choice because it encodes more characters, preventing accidental URL structure corruption.
Try It Yourself
Experiment with both encoding functions using our URL Encoder/Decoder tool. Paste any text, switch between encoding modes, and see exactly which characters get encoded and which are preserved. The tool supports encodeURIComponent, encodeURI, and form encoding side by side.
Further Reading
- MDN encodeURI()
JavaScript API reference for encoding complete URIs.
- MDN encodeURIComponent()
JavaScript API reference for encoding URI components.
- RFC 3986 — URI Generic Syntax
The IETF standard defining URI syntax and reserved characters.
- WHATWG URL Standard
The living standard for URL parsing used by web browsers.