URL Encoding and Decoding: A Complete Developer Guide
Understand percent-encoding, when to encode URLs, common pitfalls, and how to handle special characters safely in web applications.
By Belqassim Djafer · Published · Updated
What Is URL Encoding?
URL encoding (also called percent-encoding) is the process of converting characters into a format that can be safely transmitted over the Internet. A URL can only contain a limited set of printable ASCII characters. When a URL needs to include other characters — spaces, accented letters, symbols like &, =, ? — they must be encoded.
Each unsafe character is replaced by a percent sign (%) followed by two hexadecimal digits representing its ASCII code. For example:
- Space →
%20 @→%40/(when inside a query value) →%2F
Why URL Encoding Exists
URLs are transmitted as plain ASCII text over HTTP. Characters outside the safe set would either be misinterpreted by servers, break the URL structure (a literal & ends a query parameter), or cause encoding errors in transit.
The specification is defined in RFC 3986, which divides characters into:
- Unreserved:
A-Z a-z 0-9 - _ . ~— always safe, never encoded - Reserved:
: / ? # [ ] @ ! $ & ' ( ) * + , ; =— safe in their structural role, must be encoded inside values - Percent-encoded: everything else
Encoding vs. Escaping: Key Differences
Developers often confuse URL encoding with HTML escaping:
| Scenario | Mechanism | Example |
|---|---|---|
| URL query parameter | Percent-encoding | q=hello%20world |
| HTML attribute | HTML entity encoding | & |
| JavaScript string | Backslash escaping | "line\\n" |
Using the wrong method in the wrong context causes security vulnerabilities or broken functionality.
encodeURIComponent vs. encodeURI in JavaScript
JavaScript offers two built-in functions, and choosing the wrong one is a common mistake:
encodeURI
Encodes a full URL. It does NOT encode characters that are part of the URL structure:
encodeURI("https://example.com/search?q=hello world&lang=en")
// → "https://example.com/search?q=hello%20world&lang=en"
The &, =, ? and / are preserved because they are structural.
encodeURIComponent
Encodes a single value inside a URL. It encodes structural characters too:
encodeURIComponent("hello world & goodbye")
// → "hello%20world%20%26%20goodbye"
Rule of thumb: use encodeURIComponent for values you embed into query strings or path segments. Use encodeURI only for complete URLs.
Common Pitfalls
Double-Encoding
Encoding an already-encoded string produces broken output:
// Wrong: encoding twice
const value = encodeURIComponent("hello world"); // "hello%20world"
const url = `/search?q=${encodeURIComponent(value)}`; // "hello%2520world" ← broken
Always encode once, at the point of URL construction.
+ vs. %20 for Spaces
In the application/x-www-form-urlencoded format (HTML forms), spaces are encoded as +. In path segments and modern APIs, spaces must be %20. Mixing the two causes subtle bugs.
# Form submission encoding (legacy)
first+name=John+Doe
# Modern REST API path
/users/John%20Doe
Encoding Entire URLs vs. Values
A frequent mistake is calling encodeURIComponent on a full URL string:
// Wrong: encodes the structural characters
encodeURIComponent("https://example.com/path?q=value")
// → "https%3A%2F%2Fexample.com%2Fpath%3Fq%3Dvalue"
URL Encoding in Practice
Building Query Strings in JavaScript
const params = new URLSearchParams({
q: "hello world",
lang: "en",
page: 2
});
const url = `https://api.example.com/search?${params.toString()}`;
// → https://api.example.com/search?q=hello+world&lang=en&page=2
URLSearchParams handles encoding automatically and is the safest approach.
Python Requests Library
import requests
response = requests.get("https://api.example.com/search", params={
"q": "hello world",
"lang": "en"
})
# The library URL-encodes the params automatically
curl from the Command Line
curl -G "https://api.example.com/search" --data-urlencode "q=hello world" --data-urlencode "lang=en"
Security Implications
URL encoding is a first line of defence against injection attacks:
- Open Redirect: unencoded URLs in redirect parameters can be manipulated to point to malicious sites
- SSRF (Server-Side Request Forgery): unvalidated, unencoded URLs passed to server-side HTTP clients
- XSS via URL parameters: if a URL parameter is reflected into an HTML page without HTML-escaping
Always validate and encode URL components on both client and server side.
Decoding URLs Safely
When reading URL parameters, always decode:
const params = new URLSearchParams(window.location.search);
const query = params.get("q"); // automatically decoded
Never decode manually with string replacement; use the platform's built-in parser.
URL Encoding Cheat Sheet
| Character | Encoded |
|---|---|
| Space | %20 (or + in forms) |
! |
%21 |
# |
%23 |
$ |
%24 |
& |
%26 |
' |
%27 |
( |
%28 |
) |
%29 |
* |
%2A |
+ |
%2B |
, |
%2C |
/ |
%2F |
: |
%3A |
; |
%3B |
= |
%3D |
? |
%3F |
@ |
%40 |
[ |
%5B |
] |
%5D |
Conclusion
URL encoding is a small but critical detail in web development. Using the wrong encoding function, encoding twice, or skipping encoding entirely causes bugs that are hard to reproduce and potential security vulnerabilities. Always use your language's standard library for URL construction, and use our URL Encoder and URL Decoder tools to test values quickly.