URL Encoding Explained — encodeURI vs encodeURIComponent

URLs can only contain a limited set of ASCII characters. Percent-encoding (URL encoding) converts any other character into a safe %XX format. Understanding when to use encodeURI vs encodeURIComponent prevents subtle bugs in API calls, redirects, and query strings.

What URL Encoding Is

RFC 3986 defines which characters are allowed in a URL. Characters outside the allowed set must be percent-encoded: replaced with a % followed by two uppercase hex digits representing the character's UTF-8 byte value.

Space → %20 & → %26 = → %3D ? → %3F # → %23 / → %2F + → %2B @ → %40 é → %C3%A9 (UTF-8: 2 bytes → 2 percent-encoded sequences)

Which Characters Get Encoded

CategoryCharactersEncode?
UnreservedA-Z a-z 0-9 - _ . ~Never
Reserved (structure): / ? # [ ] @ ! $ & ' ( ) * + , ; =Only when used as data
Other ASCIISpaces, <, >, ", {, }, |, \, ^, `Always
Non-ASCIIé, 中, emoji, etc.Always (UTF-8 bytes)

encodeURI vs encodeURIComponent

JavaScript has two built-in encoding functions with important differences:

FunctionDoes NOT encodeUse for
encodeURI()A-Z a-z 0-9 - _ . ~ ; , / ? : @ & = + $ #A complete URL
encodeURIComponent()A-Z a-z 0-9 - _ . ~A single query param value or path segment
const path = '/search'; const query = 'hello world & more'; const url = 'https://example.com/path?q=hello world&redirect=http://other.com/path?x=1'; // encodeURI — preserves URL structure encodeURI(url); // → 'https://example.com/path?q=hello%20world&redirect=http://other.com/path?x=1' // Problem: & and = in redirect value are NOT encoded! // encodeURIComponent — encodes everything except unreserved chars encodeURIComponent(query); // → 'hello%20world%20%26%20more' // Correct approach: encode each component separately const safeUrl = `https://example.com${path}?q=${encodeURIComponent(query)}`; // → 'https://example.com/search?q=hello%20world%20%26%20more'

Query String Encoding Pitfalls

The safest way to build query strings in JavaScript is with the URLSearchParams API:

// URLSearchParams handles encoding automatically const params = new URLSearchParams({ q: 'hello world', category: 'a&b', redirect: 'https://other.com/path?x=1', }); const url = `https://api.example.com/search?${params}`; // → 'https://api.example.com/search?q=hello+world&category=a%26b&redirect=https%3A%2F%2Fother.com%2Fpath%3Fx%3D1' // Note: URLSearchParams encodes spaces as + (form encoding) // If you need %20, use encodeURIComponent manually: const qs = Object.entries({ q: 'hello world', n: 42 }) .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`) .join('&');

Python, Go, and curl Equivalents

# Python from urllib.parse import quote, quote_plus, urlencode quote('hello world & more') # 'hello%20world%20%26%20more' quote_plus('hello world & more') # 'hello+world+%26+more' (form encoding) urlencode({'q': 'hello world', 'n': 42}) # 'q=hello+world&n=42' # Go import "net/url" url.QueryEscape("hello world & more") // "hello+world+%26+more" url.PathEscape("hello world & more") // "hello%20world%20&%20more" // Proper query string building v := url.Values{} v.Set("q", "hello world") v.Set("category", "a&b") fmt.Println(v.Encode()) // "category=a%26b&q=hello+world" # curl — use --data-urlencode for automatic encoding curl -G https://api.example.com/search \ --data-urlencode "q=hello world & more"

Related Tools

Related Guides

FAQ

What is URL encoding?

URL encoding (also called percent-encoding) converts characters that are not allowed in URLs into a safe format. Each unsafe character is replaced with a % followed by two hex digits representing the character's UTF-8 byte value. For example, a space becomes %20, and & becomes %26.

When should I use encodeURIComponent vs encodeURI?

Use encodeURIComponent for individual query parameter values and URL fragments. Use encodeURI for a complete URL where you want to preserve the structure (slashes, colons, question marks). If you're building a URL from dynamic values, encodeURIComponent is almost always what you want.

Why does a space become + in some URLs?

In the application/x-www-form-urlencoded format (used by HTML forms), spaces are encoded as + rather than %20. This is the older encoding. In modern percent-encoding (RFC 3986), spaces are always %20. Some servers accept both, but %20 is more portable.

How do I encode a full URL with query parameters in JavaScript?

Use the URL and URLSearchParams APIs: const url = new URL('https://example.com/search'); url.searchParams.set('q', 'hello world'); url.toString() → 'https://example.com/search?q=hello+world'. This handles encoding automatically.

What characters are safe in a URL without encoding?

Unreserved characters are always safe: letters (A-Z, a-z), digits (0-9), and the four characters - _ . ~. These never need encoding. Reserved characters (like /, ?, #, &, =) are safe only in their structural position; if they appear as data values, they must be percent-encoded.