URL Encoder & Decoder Guide: Percent-Encoding Explained
Technical Mastery Overview
What Is URL Encoding?
URL encoding (also called percent-encoding) is the process of replacing characters that are not allowed in a URL with a % sign followed by the character's hexadecimal byte value. It is defined by RFC 3986 and is required any time data containing special characters appears inside a URL.
For example, a space cannot appear literally in a URL. The browser replaces it with %20:
https://example.com/search?q=hello world ← invalid
https://example.com/search?q=hello%20world ← valid
Without encoding, characters like &, =, #, and / break URL parsers because those characters have structural meaning in URLs. When they appear in data (not as structural delimiters), they must be encoded so parsers treat them as literal values.
How Percent-Encoding Works
Each byte of the character is represented as %XX where XX is the uppercase hexadecimal value of that byte:
| Character | UTF-8 bytes | Encoded |
|---|---|---|
| Space | 0x20 |
%20 |
& |
0x26 |
%26 |
= |
0x3D |
%3D |
# |
0x23 |
%23 |
+ |
0x2B |
%2B |
@ |
0x40 |
%40 |
/ |
0x2F |
%2F |
é |
0xC3 0xA9 |
%C3%A9 |
😊 |
0xF0 0x9F 0x98 0x8A |
%F0%9F%98%8A |
Multi-byte UTF-8 characters (accented letters, CJK, emoji) produce multiple percent-encoded pairs — that's why emoji can become 12+ characters when encoded.
RFC 3986 safe characters — never need encoding anywhere in a URL:
A–Z a–z 0–9 - _ . ~
Reserved characters — have structural meaning and must be encoded when used as literal data:
: / ? # [ ] @ ! $ & ' ( ) * + , ; =
How to Use This Tool
- Paste your URL component, query string value, or full URL into the input box
- Click Encode to percent-encode all special characters, or Decode to convert
%XXsequences back to readable text - Click Copy on the output to grab the result, or Swap to push the output back into the input for further processing
- Use Clear (↺ icon) to reset and start fresh
The tool runs entirely in your browser — nothing is transmitted to any server.
Common Use Cases
Encoding query parameter values
The most frequent use case: a query string value that contains characters like &, =, or spaces will break the URL structure if not encoded.
Before: https://api.example.com/search?q=C++ & algorithms&sort=date
After: https://api.example.com/search?q=C%2B%2B%20%26%20algorithms&sort=date
Paste the raw value (not the full URL) into our encoder to get the safe version.
Decoding OAuth and webhook callbacks
OAuth flows and webhook systems encode redirect URLs and callback parameters. Receiving a URL like this in a log:
/callback?code=4%2F0AfJohXl7g&state=abc%3D123&redirect_uri=https%3A%2F%2Fmyapp.com%2Fcb
Paste it into the decoder to instantly read it as:
/callback?code=4/0AfJohXl7g&state=abc=123&redirect_uri=https://myapp.com/cb
Useful when debugging OAuth errors, inspecting webhook payloads, or reading encoded log entries.
Building tracking and UTM URLs
UTM parameters for analytics often contain spaces and special characters:
utm_campaign=Spring Sale 2025 | Email
Encoded:
utm_campaign=Spring%20Sale%202025%20%7C%20Email
Paste individual parameter values (not the full URL) into the encoder before concatenating them into your tracking link.
Reading encoded API responses
APIs frequently return URLs inside JSON where the URL itself is percent-encoded. Decode the string to see the actual endpoint:
"redirect_url": "https%3A%2F%2Fapp.example.com%2Fauth%3Ftoken%3Dabc123"
Decoded: https://app.example.com/auth?token=abc123
The Most Common Bug: Unencoded Query Parameters
https://api.example.com/search?q=hello world&filter=type=user&sort=date
This URL has three silent problems:
- Space in
hello world— breaks the URL at the space; the parser stops reading =inside thefiltervalue — looks like a new key-value separator&separatingfiltervalue fromsort— splits the parameter mid-value
Correctly encoded:
https://api.example.com/search?q=hello%20world&filter=type%3Duser&sort=date
The parser now correctly reads:
q=hello worldfilter=type=usersort=date
encodeURIComponent vs encodeURI — Know the Difference
JavaScript has two encoding functions and confusing them is a very common mistake:
encodeURI("https://example.com/path?q=hello world&x=a=b")
// → "https://example.com/path?q=hello%20world&x=a=b"
// Encodes spaces but NOT :, /, ?, &, = — they're structural to the URL
encodeURIComponent("hello world&x=a=b")
// → "hello%20world%26x%3Da%3Db"
// Encodes EVERYTHING including &, =, /, ? — treats input as a raw value
Rule: use encodeURIComponent for individual parameter values, encodeURI for full URLs you want to make safe for HTTP transmission.
const query = "C++ programming & algorithms";
const url = `https://api.example.com/search?q=${encodeURIComponent(query)}`;
// → "https://api.example.com/search?q=C%2B%2B%20programming%20%26%20algorithms"
Our tool uses encodeURIComponent — the correct function for encoding individual query parameter values.
URL Encoding in Other Languages
Python
from urllib.parse import quote, unquote, urlencode
# Encode a single value
value = "hello world & more"
encoded = quote(value, safe='')
# → "hello%20world%20%26%20more"
# Decode
decoded = unquote("hello%20world%20%26%20more")
# → "hello world & more"
# Build a query string safely
params = {'q': 'C++ algorithms', 'filter': 'type=user'}
query_string = urlencode(params)
# → "q=C%2B%2B+algorithms&filter=type%3Duser"
PHP
// Encode a query parameter value
$value = "hello world & more";
$encoded = rawurlencode($value);
// → "hello%20world%20%26%20more"
// Decode
$decoded = rawurldecode("hello%20world%20%26%20more");
// → "hello world & more"
// Build a full query string
$params = ['q' => 'C++ algorithms', 'filter' => 'type=user'];
$qs = http_build_query($params);
// → "q=C%2B%2B+algorithms&filter=type%3Duser"
Note: PHP has both urlencode() (uses + for spaces, form convention) and rawurlencode() (uses %20, RFC 3986). Use rawurlencode for URL path segments and query values that will be used outside of HTML forms.
Go
import "net/url"
// Encode a single value
encoded := url.QueryEscape("hello world & more")
// → "hello+world+%26+more" (uses + for spaces — form encoding)
// For strict RFC 3986 percent-encoding
encoded = url.PathEscape("hello world & more")
// → "hello%20world%20&%20more"
// Build a full URL safely
params := url.Values{}
params.Set("q", "C++ algorithms")
params.Set("filter", "type=user")
fullURL := "https://api.example.com/search?" + params.Encode()
Ruby
require 'uri'
require 'cgi'
# Encode a query parameter value
encoded = URI.encode_www_form_component("hello world & more")
# → "hello+world+%26+more"
# Strict RFC 3986 encoding
encoded = CGI.escape("hello world & more")
# → "hello+world+%26+more"
# Build a query string
params = { q: "C++ algorithms", filter: "type=user" }
query_string = URI.encode_www_form(params)
The + vs %20 Space Ambiguity
Two different encodings for spaces exist in web standards:
%20— standard RFC 3986 percent-encoding, works everywhere in URLs+— only valid inapplication/x-www-form-urlencoded(HTML form submissions)
HTML forms use + for spaces; URLs use %20. Mixing them causes bugs:
// In a URL query string: %20 is correct
const url = `https://example.com/search?q=hello%20world`;
// In a form body: + is conventional
// application/x-www-form-urlencoded: q=hello+world
When decoding form-encoded strings (where + means space), use:
decodeURIComponent(str.replace(/\+/g, ' '))
decodeURIComponent alone does NOT convert + to a space — it only handles %XX sequences.
Encoding for Different URL Parts
| URL part | What to encode | JavaScript function |
|---|---|---|
| Full URL | Minimal (just illegal chars) | encodeURI() |
| Query parameter value | All reserved chars | encodeURIComponent() |
| Path segment | Reserved chars except / |
Custom or library |
Fragment (#...) |
Reserved chars | encodeURIComponent() |
| Username / password | Reserved chars | encodeURIComponent() |
Our tool encodes query parameter values — the most common use case when building API URLs.
Security: Encoding Attacks to Know
Open redirect via encoding
https://app.example.com/redirect?url=https%3A%2F%2Fevil.com
If your server decodes the url parameter and redirects without validation, an attacker can point it to any domain. Always validate redirect destinations against an allowlist after decoding, not before — decoded and encoded forms of the same attack bypass pre-decode validation.
Path traversal via double-encoding
/files/..%2F..%2Fetc%2Fpasswd
Some servers decode this to /files/../../etc/passwd and serve sensitive files. Always normalize and validate paths after decoding. Never trust the raw encoded form as proof of safety.
Second decoding attacks
A value encoded twice (%2520 decodes first to %20, which decodes again to a space) can bypass single-pass input validation. Validate after all decoding rounds are complete.
For hash-based integrity verification of URL tokens, use our Hash Generator. For JWT tokens passed in URL parameters, inspect them with our JWT Debugger.
Building API Request URLs
When constructing URLs for our cURL Generator, encode each query parameter value separately before concatenating:
# Build URL with encoded parameters (Python one-liner)
QUERY=$(python3 -c "import urllib.parse; print(urllib.parse.quote('user@example.com', safe=''))")
curl "https://api.example.com/users?email=$QUERY"
Or let the HTTP library handle it:
const params = new URLSearchParams({
email: 'user@example.com',
role: 'admin & manager'
});
fetch(`/api/users?${params}`);
// Automatically encodes → /api/users?email=user%40example.com&role=admin+%26+manager
URLSearchParams uses + for spaces (form encoding convention). If your API expects %20, convert after: .toString().replace(/\+/g, '%20').
For structured JSON request bodies that accompany these URLs, validate the payload with our JSON Formatter before sending.
Privacy: Why Encoding Locally Matters
URL strings frequently contain sensitive information — email addresses, API tokens, OAuth codes, redirect targets. Sending these to a cloud-based encoding service means the raw values traverse the network and may appear in server logs before or after encoding.
Our encoder runs encodeURIComponent and decodeURIComponent entirely in your browser. Nothing is transmitted. This is the right approach when encoding values that include credentials, private tokens, or personally identifiable information.
For encoding binary data (like images or files) rather than URL components, use our Base64 Encoder, which also processes locally.
Frequently Asked Questions
What is the difference between URL encoding and Base64 encoding?
URL encoding (percent-encoding) makes text safe for use inside URLs by replacing special characters with %XX sequences. Base64 encoding converts binary data into a 64-character ASCII alphabet, used for embedding binary content in text protocols like email or JSON. They solve different problems — use URL encoding for query parameters and URL components, Base64 for binary data payloads. See our Base64 Encoder for the latter.
Why does %20 appear instead of a space?
A space is not a valid character in a URL — it would terminate the URL at that point in many parsers. The space character has the UTF-8 byte value 0x20, so percent-encoding it produces %20. Some systems use + instead of %20 for spaces, but that only applies inside application/x-www-form-urlencoded form bodies, not in URLs.
How do I decode a URL that has been encoded twice?
Double-encoded URLs (e.g., %2520 representing a literal %20) need two rounds of decoding. Paste the string into our tool, click Decode, then click Swap to push the output back to the input, and click Decode again.
Is URL encoding the same as HTML encoding?
No. HTML encoding replaces characters like <, >, and & with HTML entities (<, >, &) to prevent them from being interpreted as HTML markup. URL encoding replaces URL-unsafe characters with %XX sequences. They are separate systems for separate contexts — though you may need both when a URL appears inside an HTML attribute.
What happens if I don't encode a URL parameter?
Unencoded special characters in query parameters cause parsers to misinterpret the URL structure. A & splits the parameter early, an = creates a new key-value pair, a # truncates the query string, and spaces break the URL entirely. The result is incorrect data reaching your server, 400 errors, or silent data corruption.
Can I encode a full URL with this tool?
The tool applies encodeURIComponent which encodes all reserved characters including :, /, ?, and &. This is correct for encoding a URL that will itself become a query parameter value (e.g., a redirect URL). If you want to make a full URL safe without encoding its structure, use encodeURI in JavaScript instead — it preserves :, /, ?, &, =, and #.
Experience it now.
Use the professional-grade URL Encoder/Decoder with zero latency and 100% privacy in your browser.