Tools
Developer Tools

URL Encoder & Decoder: The Complete Developer Guide

If you've ever seen %20 in a URL instead of a space, or wondered why & becomes %26, or why your perfectly crafted link breaks when it contains an emoji — you need to understand URL encoding. This guide covers everything you need to encode and decode URLs correctly, avoid the traps that break links in production, and understand the difference between encodeURI and encodeURIComponent.

Try the free URL Encoder & Decoder tool — it handles auto-detect, batch mode, and double-encoding detection.

What Is URL Encoding?

URL encoding, also called percent-encoding or URI encoding, is a way to represent characters inside a URL that would otherwise be illegal, ambiguous, or dangerous. URLs are defined by RFC 3986 and can only contain a very limited set of ASCII characters:

Every character outside this set must be percent-encoded: converted to a % followed by two hexadecimal digits representing the character's byte value in UTF-8. A space (U+0020) becomes %20. The question mark (U+003F) becomes %3F. An emoji like 😅 (U+1F601) becomes %F0%9F%98%81 — four encoded bytes because UTF-8 uses multiple bytes for characters outside ASCII.

⚠ Why This Matters

URLs with unencoded special characters break in unexpected ways. Some servers silently truncate at the first space. Others interpret & as a query parameter delimiter and split your value. Browsers may re-encode your URL on the fly, making it look encoded when it isn't. Always encode before transmitting a URL.

The Two Functions: encodeURI vs encodeURIComponent

This is the most common source of confusion in URL encoding. JavaScript provides two built-in functions that do different things:

encodeURIComponent() — For Individual Values

Use this when encoding a single query parameter value or path segment. It encodes everything except the ASCII alphanumeric characters and - _ . ~ ! ' ( ) * ; : @ & = + $ , / ? #. Specifically, it will encode:

encodeURIComponent("hello world")
// → "hello%20world"

encodeURIComponent("café & pastries")
// → "caf%C3%A9%20%26%20pastries"

encodeURIComponent("https://example.com")
// → "https%3A%2F%2Fexample.com"
// ⚠️ This destroys the URL structure!

encodeURI() — For Complete URLs

Use this when encoding a complete URL that you want to remain a valid URL. It preserves the characters that have structural meaning in URLs:

encodeURI("https://example.com/search?q=hello world")
// → "https://example.com/search?q=hello%20world"
// ✅ The : // ? = and space in "q=" are preserved

encodeURI("https://example.com/?q=café")
// → "https://example.com/?q=caf%C3%A9"
// ✅ The ? and = are preserved
Character encodeURIComponent() encodeURI() Reasoning
(space) %20 %20 Not allowed in any URL component
/ %2F / Path separator — must be preserved in URLs
? %3F ? Query string delimiter — must be preserved
& %26 & Query parameter separator — must be preserved
# %23 # Fragment identifier delimiter — must be preserved
= %3D = Key/value separator in query strings — preserved in encodeURI
+ %2B + + is valid in encodeURI; encoded in encodeURIComponent

The golden rule: encode your query parameter values individually with encodeURIComponent(), then assemble the full URL. Never pass a complete URL to encodeURIComponent() — you'll destroy its structure.

Common URL Encoded Characters

Here's a quick reference for the most common encoded characters you'll encounter:

Character Encoded Common Scenario
  (space)%20Any space in a query value or path
!%21Exclamation marks in query strings
"%22Quotes in URL parameters
#%23Hashes in values (not as fragment)
$%24Dollar signs in amounts/prices
%%25Percent signs — the escape character itself
&%26Ampersands in parameter values
'%27Apostrophes in names and quotes
( )%28 %29Parentheses in search queries
+%2BPlus signs in phone numbers
/%2FSlashes in encoded path segments
:%3AColons in timestamps like "10:30"
< >%3C %3EAngle brackets in text content
\%5CBackslashes in Windows paths
~%7ETildes in some encoded contexts
é%C3%A9Accented Latin letters
%E4%B8%ADMultibyte characters (Chinese, emoji, etc.)

Double Encoding: The Silent URL Killer

Double-encoding is one of the most insidious URL bugs in production. It happens when software encodes data that was already percent-encoded. The result: %20 (a space) becomes %2520 (% encoded to %25 + 20).

Original:     "Hello World" (with a space)
First encode: "Hello%20World"
Second encode: "Hello%2520World"  ← breaks here

This commonly happens through:

The most dangerous aspect of double-encoding is that it's often silent — the URL appears to work in some contexts and fail in others, making it extremely hard to debug.

🔓 Security Note

Double-encoding has been exploited in injection attacks, particularly HTTP Parameter Pollution (HPP) attacks. Attackers deliberately send double-encoded values that get decoded once by a WAF and once by the application backend, bypassing security filters. Always validate and sanitize URL parameters at the application boundary, not just encode them.

How to Decode URLs in Different Languages

JavaScript

// Decode a single value
decodeURIComponent("caf%C3%A9%20%26%20pastries")
// → "café & pastries"

// Decode a full URL (if you must)
decodeURI("https://example.com/search?q=hello%20world")
// → "https://example.com/search?q=hello world"

// Safe decode with error handling
function safeDecode(str) {
  try { return decodeURIComponent(str); }
  catch (e) { return str; }
}

Python

import urllib.parse

# Decode query parameter values
urllib.parse.unquote("caf%C3%A9%20%26%20pastries")
# → "café & pastries"

# Decode full URL
urllib.parse.unquote("https://example.com/search?q=hello%20world")
# → "https://example.com/search?q=hello world"

# For Python 3.7+
urllib.parse.parse_qs("q=hello%20world")['q']
# → ['hello world']

bash / Command Line

# Using Python
python3 -c "import urllib.parse; print(urllib.parse.unquote('Hello%20World'))"
# → Hello World

# Using printf (bash built-in)
printf '%s\n' "$(printf '%s' 'Hello%%20World' | sed 's/%\(..\)/\\x\1/g')"
# Requires printf to interpret hex sequences

The + vs %20: Why Form Data Uses Different Encoding

There's a legacy inconsistency in how HTML forms encode spaces. The application/x-www-form-urlencoded format (used by traditional HTML form submissions) converts spaces to + instead of %20. URL percent-encoding uses %20 for spaces.

application/x-www-form-urlencoded (HTML forms):
  "hello world" → "q=hello+world"

text/uri-list (URLs and JSON APIs):
  "hello world" → "q=hello%20world"

This matters when parsing query strings — the same data encoded two different ways needs different parsing logic. Most modern APIs use JSON or proper percent-encoding, but you'll still encounter the + format in legacy systems.

Encoding URLs in Email and SMS

One of the most common real-world URL encoding problems is email and SMS links containing special characters. Email clients, SMS apps, and link shorteners may handle percent-encoded URLs differently:

Best practice for marketing URLs: always encode the full URL before embedding it in email templates, SMS messages, or QR codes. Test the URL by clicking it from within the target application — not just by pasting it in a browser.

How the SnapUtils URL Encoder & Decoder Helps

The URL Encoder & Decoder tool at SnapUtils handles the real-world scenarios that most online encoders miss:

Try the URL Encoder & Decoder

Instantly encode and decode URLs. Auto-detect, batch mode, and double-encoding detection.

Open Tool →

Quick Reference: Encoding Checklist