URL Encoding in JavaScript — encodeURIComponent vs encodeURI
JavaScript has two URL encoding functions: encodeURI for full URLs and encodeURIComponent for individual components. Learn the difference, when to use each, how to encode query...
Use the tool
URL Encoder / Decoder
Percent-encode and decode URLs per RFC 3986.
JavaScript has two URL encoding functions with subtly different purposes. Using the wrong one is a common bug that causes broken URLs in production.
Use the URL Encoder to encode and decode URLs instantly.
encodeURI vs encodeURIComponent
// encodeURI: encodes a FULL URL — leaves :, /, ?, &, =, #, @ intact
encodeURI('https://example.com/path?q=hello world&lang=en')
// 'https://example.com/path?q=hello%20world&lang=en'
// Notice: :, /, ?, &, = are preserved (needed for URL structure)
// encodeURIComponent: encodes a URL COMPONENT — encodes :, /, ?, &, =, # too
encodeURIComponent('hello world & more')
// 'hello%20world%20%26%20more'
encodeURIComponent('https://example.com/path')
// 'https%3A%2F%2Fexample.com%2Fpath'
Rule of thumb:
- Use
encodeURIwhen you have a complete URL and want to make it safe for transmission - Use
encodeURIComponentfor individual values that go INTO a URL (query param values, path segments)
Common mistake: encoding query parameter values
const query = 'fish & chips';
const category = 'food/drinks';
// WRONG: encodeURI won't encode & or /
const url = `https://api.com/search?q=${encodeURI(query)}&cat=${encodeURI(category)}`;
// 'https://api.com/search?q=fish & chips&cat=food/drinks' ← broken!
// RIGHT: encodeURIComponent for each value
const url = `https://api.com/search?q=${encodeURIComponent(query)}&cat=${encodeURIComponent(category)}`;
// 'https://api.com/search?q=fish%20%26%20chips&cat=food%2Fdrinks' ✓
Build URLs safely with URLSearchParams
// URLSearchParams handles encoding automatically:
const params = new URLSearchParams({
q: 'fish & chips',
category: 'food/drinks',
page: 1,
sort: 'relevance',
});
const url = `https://api.example.com/search?${params}`;
// 'https://api.example.com/search?q=fish+%26+chips&category=food%2Fdrinks&page=1&sort=relevance'
// Note: URLSearchParams uses + for spaces (form encoding), not %20
// Append multiple values for same key:
const params = new URLSearchParams();
params.append('tag', 'javascript');
params.append('tag', 'css');
params.append('tag', 'html');
// 'tag=javascript&tag=css&tag=html'
Decode URLs
// decodeURIComponent: decodes encoded characters
decodeURIComponent('fish%20%26%20chips') // 'fish & chips'
decodeURIComponent('hello+world') // 'hello+world' (+ is NOT decoded)
// Note: + as space is application/x-www-form-urlencoded convention
// Replace + before decoding for form data:
function decodeFormValue(str) {
return decodeURIComponent(str.replace(/\+/g, ' '));
}
decodeFormValue('hello+world') // 'hello world'
decodeFormValue('fish+%26+chips') // 'fish & chips'
// Parse query string:
const qs = '?q=fish+%26+chips&page=2';
const params = new URLSearchParams(qs);
params.get('q') // 'fish & chips' (URLSearchParams handles + automatically)
params.get('page') // '2'
URL class for robust URL manipulation
// URL class: construct and manipulate URLs safely
const url = new URL('https://example.com/search');
url.searchParams.set('q', 'fish & chips');
url.searchParams.set('page', '2');
url.pathname = '/api/v2/search';
url.toString()
// 'https://example.com/api/v2/search?q=fish+%26+chips&page=2'
// Parse existing URL:
const parsed = new URL('https://user:pass@example.com:8080/path?q=hello#section');
parsed.hostname // 'example.com'
parsed.port // '8080'
parsed.pathname // '/path'
parsed.search // '?q=hello'
parsed.hash // '#section'
parsed.username // 'user'
Encode path segments
// Path segments need encodeURIComponent (encode /)
// but typically you want / preserved in the path:
const userId = 'user/with/slashes';
const filename = 'my file.pdf';
// Each segment encoded separately:
const path = `/users/${encodeURIComponent(userId)}/files/${encodeURIComponent(filename)}`;
// '/users/user%2Fwith%2Fslashes/files/my%20file.pdf'
// The URL object handles this too:
const url = new URL('https://example.com');
url.pathname = `/files/${encodeURIComponent(filename)}`;
url.toString()
// 'https://example.com/files/my%20file.pdf'
Characters that DON’T need encoding
// These are "unreserved characters" — safe in any URL component:
// A-Z a-z 0-9 - _ . ~
// encodeURIComponent does NOT encode these:
encodeURIComponent('hello-world_test.file~123')
// 'hello-world_test.file~123' (unchanged)
// Everything else gets percent-encoded
encodeURIComponent('hello world!')
// 'hello%20world!'
Related tools
- URL Encoder — encode and decode URLs online
- URL Encoding in Python — Python urllib.parse
- URL Encoding Guide — what to encode and when
Related posts
- URL Encoding: The 7 Bugs That Break Your API — Every API has at least one URL-encoding bug. Here are the seven I see most — wha…
- Percent Encoding and RFC 3986 Explained — Why is `+` sometimes a space and sometimes a literal plus? Why does `%2520` show…
- Double URL Encoding — What It Is, Why It Happens, and How to Prevent It — Double URL encoding happens when an already-encoded URL is encoded again, turnin…
- URL Encode Decode — Encode and Decode URLs Online — URL encoding converts special characters to percent-encoded sequences (%20 for s…
- URL Encoding in Python — urllib.parse, requests, and FastAPI — Python's urllib.parse module provides quote, quote_plus, and urlencode for URL e…
Related tool
URL Encoder / Decoder
Percent-encode and decode URLs per RFC 3986.
Written by Mian Ali Khalid. Part of the Dev Productivity pillar.