Should I encode spaces as %20 or + in URLs?
Both %20 and + can represent spaces, but they're used in different contexts.
The Short Answer:
- Use
%20everywhere (modern standard) - Use
+only in legacy query strings (older form submissions)
The Details:
%20 (Percent-20):
- Works everywhere in URLs (path, query, fragment)
- Modern standard for all URL encoding
- Produced by
encodeURIComponent()andencodeURI() - Safe and unambiguous
+ (Plus Sign):
- Only valid in query strings (after the
?) - Legacy from application/x-www-form-urlencoded format
- Used by HTML forms with GET method
- Can be ambiguous (is it a plus or a space?)
Examples:
URL Paths - Use %20:
Good: /files/my%20document.pdf
Bad: /files/my+document.pdf (treated as literal plus)
Query Strings - Both work:
Modern: ?name=John%20Doe
Legacy: ?name=John+Doe (still works)
Fragments - Use %20:
Good: #section%20one
Bad: #section+one (treated as literal plus)
Which Should You Use?
Always use %20 if you're:
- Writing modern code
- Building APIs
- Working with RESTful URLs
- Want consistency
- Encoding entire URLs
- Encoding URL paths
Use + only if:
- Maintaining legacy systems
- Mimicking HTML form encoding
- Specifically need application/x-www-form-urlencoded format
JavaScript Functions:
// Use these - they produce %20
encodeURIComponent("Hello World") // "Hello%20World"
encodeURI("Hello World") // "Hello%20World"
// Don't use this - deprecated
escape("Hello World") // "Hello%20World" (but deprecated)
// Form encoding uses +
new URLSearchParams({q: "Hello World"}).toString() // "q=Hello+World"
The Problem with +:
In query strings, + is ambiguous:
?math=1+1 // Is this "1 1" or "1+1"?
?math=1%2B1 // Clearly "1+1"
?math=1%201 // Clearly "1 1"
Best Practice:
Use %20 everywhere for consistency:
// Good
const url = `/search?q=${encodeURIComponent(query)}`;
// Also good (for query params)
const params = new URLSearchParams({ q: query });
const url = `/search?${params}`; // Will use +, but that's okay
Decoding:
Both decode correctly:
decodeURIComponent("Hello%20World") // "Hello World"
decodeURIComponent("Hello+World") // "Hello+World" (literal plus!)
// For query strings with +, use:
"Hello+World".replace(/+/g, " ") // "Hello World"
// Or URLSearchParams handles it automatically
Summary:
- Modern code: Always use
%20 - Legacy systems:
+in query strings is okay - When in doubt:
%20is always correct - Never use
+in URL paths or fragments