Why URLs Need Encoding
The URL specification (RFC 3986) defines a limited set of allowed characters. Characters outside this set — spaces, Unicode, special symbols — must be encoded as % followed by their two-digit hex value. This ensures URLs can be safely transmitted over systems that might otherwise misinterpret certain bytes.
Safe Characters (No Encoding Needed)
These characters are allowed in URLs without encoding:
- Unreserved:
A–Z a–z 0–9 - _ . ~ - Reserved (structural):
: / ? # [ ] @ ! $ & ' ( ) * + , ; =— these have special meaning in URL structure
Everything else must be percent-encoded.
Common Encodings
Space → %20 (or + in query strings)
# → %23
% → %25
& → %26
+ → %2B (when literal, not space in form data)
= → %3D
? → %3F
/ → %2F (when inside a path component)
@ → %40
€ → %E2%82%AC (UTF-8: E2 82 AC)
中 → %E4%B8%AD (UTF-8: E4 B8 AD)
encodeURI vs encodeURIComponent
JavaScript has two encoding functions with importantly different behavior:
// encodeURI — encodes a full URL
// Does NOT encode: : / ? # [ ] @ ! $ & ' ( ) * + , ; =
encodeURI("https://example.com/path?q=hello world&lang=en")
// "https://example.com/path?q=hello%20world&lang=en"
// encodeURIComponent — encodes a URL component (query value, path segment)
// DOES encode: : / ? # [ ] @ ! $ & ' ( ) * + , ; =
encodeURIComponent("hello world & more")
// "hello%20world%20%26%20more"
encodeURIComponent("https://example.com")
// "https%3A%2F%2Fexample.com" ← / and : are encoded
When to Use Which
- Use
encodeURIComponentfor individual query parameter names and values. - Use
encodeURIonly if you already have a full URL that you want to escape minimally. - Never use the deprecated
escape()— it doesn't handle Unicode correctly.
Building URLs Safely
// Bad — manual string concatenation is a bug waiting to happen
const url = `/search?q=${userInput}&lang=en`;
// Good — URLSearchParams handles encoding automatically
const params = new URLSearchParams({ q: userInput, lang: "en" });
const url = `/search?${params}`;
// Also good — URL constructor
const url = new URL("https://api.example.com/search");
url.searchParams.set("q", userInput);
url.searchParams.set("lang", "en");
url.toString();
Decoding
decodeURIComponent("hello%20world%20%26%20more")
// "hello world & more"
// In Node.js
new URL("https://example.com/path?q=hello%20world").searchParams.get("q")
// "hello world"
The + vs %20 Difference
In HTML form submissions with application/x-www-form-urlencoded encoding, spaces are encoded as +. In URLs, spaces should be %20. The two are different contexts:
- Query string from HTML form:
?q=hello+world - Manually constructed URL:
?q=hello%20world
Most URL parsers treat both as spaces in query strings, but be consistent within your codebase.
Encode and Decode URLs Instantly
Use ToolsVito's URL Encoder/Decoder to encode or decode any URL or component, with support for full URL and component-level encoding — directly in your browser.