URL Encoder
Convert text with special characters into a URL-safe format. Percent-encoding replaces unsafe characters with %XX codes.
Why URL Encoding Is Necessary
| Character | Issue | Encoded |
|---|---|---|
| (space) | Terminates URLs | %20 or + |
| & | Separates parameters | %26 |
| = | Separates key/value | %3D |
| ? | Starts query string | %3F |
| # | Starts fragment | %23 |
URL Encode Implementation
``javascript
// Encode for query parameters (most common)
function urlEncode(text) {
return encodeURIComponent(text);
}
// Encode full URL (preserves URL structure)
function urlEncodeFull(url) {
return encodeURI(url);
}
// Encode with + for spaces (form encoding)
function urlEncodeFormData(text) {
return encodeURIComponent(text).replace(/%20/g, '+');
}
// Examples
urlEncode('Hello World!'); // "Hello%20World%21"
urlEncode('price=100&qty=2'); // "price%3D100%26qty%3D2"
`
Building Encoded URLs
`javascript
function buildUrl(base, params) {
const searchParams = new URLSearchParams();
for (const [key, value] of Object.entries(params)) {
searchParams.append(key, value);
}
return ${base}?${searchParams.toString()};
}
`
Use this encoder to safely include any text in URLs.
What Percent-Encoding Escapes
Percent-encoding replaces a byte with % followed by its two hex digits. Which bytes need
escaping depends on where in the URL they appear, which is why JavaScript ships two
different functions.
| Character | Encoded | Why |
|---|---|---|
| space | %20 (or + in a form body) | Terminates the URL in some parsers |
& | %26 | Separates query parameters |
= | %3D | Separates key from value |
? | %3F | Starts the query string |
# | %23 | Starts the fragment |
/ | %2F | Path separator |
+ | %2B | Means a space in form encoding |
Γ© | %C3%A9 | Two UTF-8 bytes |
`javascript
encodeURI('https://ex.com/a b?x=1&y=2');
// 'https://ex.com/a%20b?x=1&y=2' β structure preservedencodeURIComponent('a b?x=1&y=2');
// 'a%20b%3Fx%3D1%26y%3D2' β everything escaped
`
Use encodeURI on a whole URL and encodeURIComponent on each value you insert into
one. Getting this backwards is the single most common URL bug: encodeURI on a query value
leaves & intact, and a value containing & then splits into two parameters.
Better still, let the platform build it:
`javascript
const url = new URL('https://example.com/search');
url.searchParams.set('q', 'a b & c'); // escaping handled
`
Encoding Is Not Encryption
Base64 and percent-encoding both make data safe to *transport*. Neither makes it secret β
both are trivially reversible by design, with no key involved. A Base64 string in a URL, a
cookie or a header is readable by anyone who sees it.
| Purpose | Use |
|---|---|
| Safe transport of binary over text | Base64 |
| Safe transport of text in a URL | Percent-encoding |
| Confidentiality | AES-GCM, TLS |
| Integrity | HMAC, a digital signature |
| Password storage | bcrypt, scrypt, Argon2 |
Size Costs
Base64 expands data by exactly 4/3 β three bytes become four characters β plus padding. A
100 KB image becomes about 133 KB as a data URI, and it cannot be cached separately from the
document that carries it. Inline small icons; link everything else.
Percent-encoding expands unpredictably: an ASCII character that needs escaping becomes three
characters, and a non-ASCII character becomes three per UTF-8 byte. Γ© is %C3%A9 β six
characters for one letter.
UTF-8 Is the Only Sane Default
Every encoding decision on the modern web assumes UTF-8. Where it goes wrong:
btoathrows on non-Latin-1 input.Encode to UTF-8 bytes first:
btoa(String.fromCharCode(...new TextEncoder().encode(text))).
atobreturns Latin-1.Decode back withnew TextDecoder().decode(bytes).- A BOM breaks parsers. Excel writes one at the start of CSV exports; strip it before
parsing.
Length is ambiguous."π¨βπ©βπ§".lengthis 8 in JavaScript, 1 to a reader. Use
Intl.Segmenter` when the count is shown to a person.