urlencodingjavascript

URL Encoding Explained: encodeURI vs encodeURIComponent

· Cosyslabs

URL encoding converts characters that are not allowed in URLs into percent-encoded equivalents using the format %XX where XX is the hexadecimal ASCII code. Use encodeURIComponent to encode individual query parameter values and path segments. Use encodeURI only when encoding a complete URL while preserving its structural characters.

Why URL Encoding Exists

URLs can only contain a limited set of ASCII characters. Characters outside this set — including spaces, Unicode characters, and many punctuation marks — must be percent-encoded before being placed in a URL.

The allowed characters without encoding are:

  • Letters: A–Z, a–z
  • Digits: 0–9
  • Unreserved symbols: -, _, ., ~
  • Reserved structural characters: :, /, ?, #, [, ], @, !, $, &, ', (, ), *, +, ,, ;, =

Everything else requires percent-encoding.

How Percent-Encoding Works

A percent-encoded character is written as % followed by two uppercase hex digits representing the byte value:

Space → %20
@ → %40
/ → %2F
? → %3F
= → %3D
& → %26
+ → %2B
# → %23

For multi-byte UTF-8 characters, each byte is encoded separately:

é  → %C3%A9   (UTF-8: 0xC3 0xA9)
中 → %E4%B8%AD (UTF-8: 0xE4 0xB8 0xAD)

encodeURIComponent vs encodeURI

JavaScript provides two encoding functions that differ in which characters they leave unencoded.

encodeURIComponent

Encodes everything except: A–Z a–z 0–9 - _ . ! ~ * ' ( )

Use this for encoding values that go inside a URL — query parameter values, path segments that contain special characters.

encodeURIComponent("hello world");     // "hello%20world"
encodeURIComponent("user@example.com"); // "user%40example.com"
encodeURIComponent("price=10&qty=2");  // "price%3D10%26qty%3D2"
encodeURIComponent("https://example.com"); // "https%3A%2F%2Fexample.com"

encodeURI

Encodes everything except: A–Z a–z 0–9 - _ . ! ~ * ' ( ) plus : / ? # [ ] @ ! $ & ' ( ) * + , ; =

Use this for encoding a complete URL where you want to preserve structural characters.

encodeURI("https://example.com/path with spaces?q=hello world");
// "https://example.com/path%20with%20spaces?q=hello%20world"

// But it does NOT encode & = ? / : which are structural
encodeURI("https://example.com?a=1&b=2");
// "https://example.com?a=1&b=2"  (unchanged — & and = preserved)

The Key Difference

const search = "coffee & cake";

// Wrong: encodeURI does not encode & so it breaks query string parsing
const wrongUrl = `https://example.com/search?q=${encodeURI(search)}`;
// https://example.com/search?q=coffee%20&%20cake  ← & splits the param!

// Correct: encodeURIComponent encodes & to %26
const rightUrl = `https://example.com/search?q=${encodeURIComponent(search)}`;
// https://example.com/search?q=coffee%20%26%20cake  ← correct

Building URLs Correctly

Manual String Concatenation (avoid)

// Fragile — easy to forget encoding
const url = `https://api.example.com/search?q=${query}&lang=${lang}`;
const params = new URLSearchParams({
  q: "coffee & cake",
  lang: "en",
  page: 1,
});

const url = `https://api.example.com/search?${params.toString()}`;
// https://api.example.com/search?q=coffee+%26+cake&lang=en&page=1

Note: URLSearchParams uses + for spaces (application/x-www-form-urlencoded format) rather than %20. Both are valid in query strings.

Using the URL API (most robust)

const url = new URL("https://api.example.com/search");
url.searchParams.set("q", "coffee & cake");
url.searchParams.set("lang", "en");
url.pathname = `/users/${encodeURIComponent(username)}/profile`;

console.log(url.toString());
// https://api.example.com/users/john%40doe/profile?q=coffee+%26+cake&lang=en

Common Mistakes

Encoding the Entire URL with encodeURIComponent

// Wrong — encodes the : and / making the URL invalid
const url = encodeURIComponent("https://example.com/path?q=hello");
// "https%3A%2F%2Fexample.com%2Fpath%3Fq%3Dhello"  ← broken URL

// Correct — encode only the value
const value = encodeURIComponent("hello world");
const url = `https://example.com/path?q=${value}`;

Double-Encoding

// Wrong — already encoded string gets encoded again
const encoded = "hello%20world";
const doubleEncoded = encodeURIComponent(encoded);
// "hello%2520world"  ← %25 is the encoding of %

// Check before encoding
function safeEncode(str) {
  try {
    // If decoding succeeds without error, it may already be encoded
    const decoded = decodeURIComponent(str);
    return decoded === str ? encodeURIComponent(str) : str;
  } catch {
    return encodeURIComponent(str);
  }
}

Forgetting to Encode Path Segments

// Wrong — / in username breaks the path
const username = "john/doe";
const url = `https://example.com/users/${username}`;
// https://example.com/users/john/doe  ← "doe" becomes a separate segment

// Correct
const url = `https://example.com/users/${encodeURIComponent(username)}`;
// https://example.com/users/john%2Fdoe

Using + as Space Outside Query Strings

The + character represents a space only in application/x-www-form-urlencoded content (HTML form submissions). In URL paths, + is a literal plus sign, not a space.

Path: /search/hello+world   → "hello+world" (literal +, wrong)
Path: /search/hello%20world → "hello world" (correct)

Query: ?q=hello+world       → "hello world" (valid in query strings)
Query: ?q=hello%20world     → "hello world" (also valid)

Decoding

decodeURIComponent("hello%20world");     // "hello world"
decodeURIComponent("user%40example.com"); // "user@example.com"
decodeURIComponent("%E4%B8%AD");         // "中"

// Always wrap in try/catch — malformed sequences throw URIError
try {
  const decoded = decodeURIComponent(userInput);
} catch (e) {
  console.error("Invalid percent-encoding:", e);
}

Try It Now

Encode and decode URLs instantly with the URL Encoder/Decoder Tool — choose between full URL encoding and component encoding modes.

More Tools from Cosyslabs

  • Unit Convert All — Convert measurement values before embedding them in query parameters (e.g., temperature, weight, distance). Handles the unit conversion step so you only need to percent-encode the final value.
  • PDF Convert All — Process and convert PDFs online. PDF download links often require URL-encoded filenames — this context is a practical example of encodeURIComponent in action.
  • Rough Estimator — Estimate development time and cost for web projects, including tasks like implementing URL-safe routing in SPAs.
  • Cosyslabs — The studio behind Dev Tools !, Routine Toolkit, Astrilio, CastFleet, and more.