DevBench
All articles
javascriptweburls

URL Encoding: encodeURIComponent vs encodeURI Explained

May 3, 20264 min read

JavaScript has two built-in URL encoding functions and developers mix them up constantly. Using the wrong one either produces broken URLs or silently leaves characters unencoded that should be escaped. Here's the precise rule for each.

What is percent-encoding?

URLs can only contain a limited set of ASCII characters. Any other character — including spaces, non-Latin letters, and many punctuation marks — must be converted to a %XX sequence where XX is the character's hexadecimal UTF-8 byte value. A space becomes %20, a euro sign € becomes %E2%82%AC.

encodeURIComponent — for individual values

encodeURIComponent() encodes everything except:

A-Z a-z 0-9 - _ . ! ~ * ' ( )

This means it encodes structural URL characters like / ? # @ & = + :. That's intentional — you're encoding a value, not a URL, so those characters should be escaped so they can't be misinterpreted as URL structure.

const query = encodeURIComponent("hello world & more");
// → "hello%20world%20%26%20more"

const url = `https://api.example.com/search?q=${query}`;
// → "https://api.example.com/search?q=hello%20world%20%26%20more"

Use this for: query parameter values, path segment values, form field data.

encodeURI — for complete URLs

encodeURI() encodes everything except characters that are legal in a complete URL:

A-Z a-z 0-9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , #

It deliberately leaves / ? # & = + : intact because it assumes those are structural URL characters, not data values.

const url = encodeURI("https://example.com/path with spaces?q=hello");
// → "https://example.com/path%20with%20spaces?q=hello"
// Note: the ? and = are preserved (they're structure)
// But the space in the path is encoded

Use this for: encoding a complete URL that may contain spaces or non-ASCII characters, but whose structure (://, ?, &, =) should be preserved.

The most common mistake

Using encodeURI() for query parameter values. If your value contains & (e.g. a company name "AT&T"), encodeURI() won't encode it — breaking the query string. Always use encodeURIComponent() for values.

The modern alternative: URLSearchParams

In modern JavaScript, you rarely need either function directly. Use URLSearchParams which handles encoding automatically:

const params = new URLSearchParams({
  q: "hello world & more",
  page: "1",
});
const url = `https://api.example.com/search?${params}`;
// → "https://api.example.com/search?q=hello+world+%26+more&page=1"

Note that URLSearchParams uses + for spaces (application/x-www-form-urlencoded) while encodeURIComponent() uses %20. Both are valid in query strings; most servers handle both.

Try it yourself

Use the free browser-based URL Encoder / Decoder on DevBench — no signup, runs entirely in your browser.

Open URL Encoder / Decoder