URL Encoding (Percent-Encoding)
URL encoding (percent-encoding) is an RFC 3986 mechanism that converts reserved or unsafe characters in a URI into a percent sign followed by two hex digits.
URL Encoding, officially specified as Percent-Encoding in IETF RFC 3986, is a standard mechanism for representing arbitrary data within Uniform Resource Identifiers (URIs). It replaces characters that have reserved structural roles (such as ?, &, /, and #) or characters outside the printable ASCII range (including spaces, emojis, and non-Latin alphabets) with a percent sign (%) followed by two hexadecimal digits representing the character's UTF-8 byte value.
Safely encode and decode query parameters, path components, or entire URLs with our client-side URL Encoder & Decoder tool.
Technical Specifications at a Glance
| Specification | RFC 3986 (URI Standard) | application/x-www-form-urlencoded |
|---|---|---|
| Standard Reference | RFC 3986 §2.1 | W3C HTML5 Form Specification |
| Primary Use Case | Full URIs, REST paths, modern APIs | HTML form submissions (POST/GET) |
| Space Encoding | %20 |
+ (Plus sign) |
| Unreserved Set | A-Z, a-z, 0-9, -, ., _, ~ |
A-Z, a-z, 0-9, *, -, ., _ |
| Encoding Format | %[0-9A-F]{2} |
%[0-9A-F]{2} (Spaces replaced with +) |
Reserved vs Unreserved Characters
RFC 3986 categorizes all URI characters into two distinct groups:
1. Unreserved Characters (Never Encoded)
Characters that carry no syntactic meaning in URI parsing and must never be percent-encoded:
- Uppercase letters:
A–Z - Lowercase letters:
a–z - Decimal digits:
0–9 - Punctuation marks: Hyphen (
-), Period (.), Underscore (_), and Tilde (~)
2. Reserved Characters (Must Be Encoded When Used as Data)
Characters that act as structural delimiters separating the protocol, host, port, path, query parameters, and fragment identifier. When included as literal data inside parameters, they must be percent-encoded:
| Character | Name | Percent-Encoded Value | Architectural Function in URI |
|---|---|---|---|
|
Space | %20 (or +) |
Invalid in raw URLs; separates query terms |
/ |
Forward Slash | %2F |
Path segment delimiter |
? |
Question Mark | %3F |
Query string delimiter |
& |
Ampersand | %26 |
Query parameter delimiter |
= |
Equals | %3D |
Key-value separator |
# |
Hash / Octothorpe | %23 |
Client-side fragment / anchor delimiter |
: |
Colon | %3A |
Scheme and port delimiter |
@ |
At symbol | %40 |
Userinfo credential delimiter |
% |
Percent sign | %25 |
Percent-encoding escape sequence indicator |
JavaScript: encodeURI vs encodeURIComponent vs URLSearchParams
Choosing the wrong encoding method in JavaScript is one of the most common causes of broken API routes:
| Feature | encodeURI() |
encodeURIComponent() |
new URLSearchParams() |
|---|---|---|---|
| Target Scope | Complete URI strings | A single query key or value | Query string key-value dictionaries |
Encodes / and ? |
No (Preserves URL structure) | Yes (Treats as literal data) | Yes (Treats as literal data) |
Encodes & and = |
No (Preserves query pairs) | Yes (Prevents parameter hijacking) | Yes |
| Space Format | %20 |
%20 |
+ |
| Correct Usage | encodeURI("https://example.com/search?q=a") |
"q=" + encodeURIComponent("C++ & C#") |
params.set("q", "C++ & C#") |
// ❌ WRONG: encodeURI preserves '&' and '=', breaking parameter parsing
const query = "DevFlow & Co = Great";
const badUrl = encodeURI(`https://api.wtool.dev/search?q=${query}`);
// Result: https://api.wtool.dev/search?q=DevFlow%20&%20Co%20=%20Great (Broken!)
// ✅ CORRECT: encodeURIComponent cleanly isolates parameter data
const safeUrl = `https://api.wtool.dev/search?q=${encodeURIComponent(query)}`;
// Result: https://api.wtool.dev/search?q=DevFlow%20%26%20Co%20%3D%20Great
// 🏆 BEST PRACTICE: Use standard URL and URLSearchParams APIs
const url = new URL("https://api.wtool.dev/search");
url.searchParams.set("q", query);
url.searchParams.set("tag", "web/crypto");
console.log(url.toString());
// Result: https://api.wtool.dev/search?q=DevFlow+%26+Co+%3D+Great&tag=web%2Fcrypto
Python 3: urllib.parse Implementation
import urllib.parse
# 1. Encode query dictionary (application/x-www-form-urlencoded)
params = {"q": "Python & FastAPI", "sort": "date/asc"}
query_string = urllib.parse.urlencode(params)
# Output: 'q=Python+%26+FastAPI&sort=date%2Fasc'
# 2. Strict RFC 3986 percent-encoding (%20 instead of +)
rfc_query = urllib.parse.quote("Python & FastAPI")
# Output: 'Python%20%26%20FastAPI'
# 3. Decoding percent-encoded URLs
decoded = urllib.parse.unquote("https%3A%2F%2Fwtool.dev%2Ftools%3Fref%3Dhome")
# Output: 'https://wtool.dev/tools?ref=home'
Frequently Asked Questions
Why is a space encoded as both %20 and +?
Both representations are valid depending on the context:
%20is the strict standard defined by RFC 3986 for all URI components.+originates from early HTML form specifications (application/x-www-form-urlencoded). When processing query strings, web servers generally interpret both+and%20as space characters.
What happens if you double-encode a URL?
Double encoding occurs when an already percent-encoded string is passed to an encoder a second time. The existing % characters are re-encoded as %25, transforming %20 into %2520. This corrupts URL parameters and frequently causes 404 Not Found or 400 Bad Request routing errors in web applications.
How are multi-byte UTF-8 characters (like emojis) encoded?
Each character is first converted into its sequence of UTF-8 octets (bytes), and each byte is independently percent-encoded. For example, the rocket emoji (🚀) has the 4-byte UTF-8 representation 0xF0 0x9F 0x99 0x80. When URL encoded, it becomes %F0%9F%99%80.
Does URL encoding protect against XSS or SQL Injection?
No. URL encoding only ensures safe transport across HTTP network layers. Once the backend server decodes the URL parameter back into raw text, the resulting payload can still execute SQL queries or script injections if rendered without parameterization or HTML Entities escaping.
Interactive Tools for URL Encoding (Percent-Encoding)
Free, browser-based utilities to test, generate, and inspect URL Encoding (Percent-Encoding) payloads directly.
URL Encoder/Decoder
web-codeEncode, decode, and parse URLs and query strings instantly.
Base64 Encode/Decode
text-dataEncode and decode Base64 strings, files, and data URIs instantly.
HTML Entities Encoder/Decoder
web-codeEncode and decode HTML entities with named, numeric, and hex modes.
cURL to Code Converter
web-codeConvert cURL commands to idiomatic code across 14 programming languages instantly.