Skip to main content
Loading time...

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 that encodeURI() 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:

CharacterencodeURI()encodeURIComponent()
: / ? # [ ] @Not encoded (preserved)Encoded
! $ & ' ( ) * + , ; =Not encoded (preserved)Encoded
SpaceEncoded as %20Encoded as %20
Non-ASCII (e.g. é, ü)EncodedEncoded

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 chars

Notice 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 segment

Form 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 structure

The 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 untouched
  • decodeURIComponent() 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 decoded

A 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:

LanguageLike encodeURILike encodeURIComponent
Pythonurllib.parse.quote(s, safe='/:?#[]@!$&'()*+,;=')urllib.parse.quote(s, safe='')
Gourl.PathEscape()url.QueryEscape()
PHPN/A (manual)rawurlencode()
RubyURI.encode_www_form_component() (partial)CGI.escape()
JavaN/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:

  1. Are you encoding a complete URL? Use encodeURI() or, better yet, the URL constructor.
  2. Are you encoding a query parameter value? Use encodeURIComponent() or URLSearchParams.set().
  3. Are you encoding a path segment? Use encodeURIComponent().
  4. Are you encoding form data? Use URLSearchParams (which handles the + for spaces convention).
  5. 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