URL Encoding Special Characters Explained

Why does a space become %20? Why does your API break when you pass an ampersand? Here's everything about URL encoding (percent encoding) in plain language.

πŸ”— Encode URLs Instantly

Paste any text and get properly URL-encoded output β€” handles spaces, Unicode, and all special characters.

Open URL Encoder β†’

What Is URL Encoding?

URL encoding (also called percent encoding) is a way to represent characters in a URL that would otherwise be invalid or ambiguous. It works by replacing unsafe characters with a % sign followed by two hexadecimal digits representing the character's byte value.

For example:

This exists because URLs have a strict syntax where certain characters have special meanings. An & separates query parameters. An = separates keys from values. A / separates path segments. If your actual data contains these characters, they need to be encoded to avoid being misinterpreted.

Characters That Need Encoding

CharacterEncodedWhy It Needs Encoding
Space%20 or +Not allowed in URLs
!%21Reserved (sub-delimiter)
#%23Fragment identifier
$%24Reserved (sub-delimiter)
&%26Query parameter separator
'%27Reserved (sub-delimiter)
(%28Reserved (sub-delimiter)
)%29Reserved (sub-delimiter)
+%2BMeans space in query strings
,%2CReserved (sub-delimiter)
/%2FPath separator
:%3AScheme/port separator
;%3BParameter delimiter
=%3DKey-value separator
?%3FQuery string start
@%40User info separator
[%5BReserved (IP literal)
]%5DReserved (IP literal)

Characters That DON'T Need Encoding

These characters are "unreserved" and safe to use anywhere in a URL without encoding:

The Space Problem: %20 vs +

Spaces are the most commonly encoded character, and there are two ways to represent them:

// In a path: use %20
https://example.com/my%20file.pdf

// In a query string: + is also valid
https://example.com/search?q=hello+world
https://example.com/search?q=hello%20world  // Also valid

When in doubt, %20 works everywhere. + only works in query strings.

URL Encoding in Different Languages

JavaScript

// encodeURIComponent β€” for query parameter VALUES (most common)
encodeURIComponent('hello world & goodbye')
// "hello%20world%20%26%20goodbye"

// encodeURI β€” for complete URLs (preserves :, /, ?, #, etc.)
encodeURI('https://example.com/path?q=hello world')
// "https://example.com/path?q=hello%20world"

// Decode
decodeURIComponent('hello%20world')  // "hello world"
decodeURI('https://example.com/hello%20world')  // Preserves structure

Common mistake: Using encodeURI() when you mean encodeURIComponent(). If you're encoding a query parameter value, always use encodeURIComponent().

Python

from urllib.parse import quote, quote_plus, unquote

# quote β€” percent encoding (for path segments)
quote('hello world & goodbye')
# 'hello%20world%20%26%20goodbye'

# quote_plus β€” form encoding (spaces become +)
quote_plus('hello world & goodbye')
# 'hello+world+%26+goodbye'

# Full URL encoding
from urllib.parse import urlencode
params = {'q': 'hello world', 'lang': 'en'}
urlencode(params)
# 'q=hello+world&lang=en'

# Decode
unquote('hello%20world')  # 'hello world'

PHP

// urlencode β€” for query strings (spaces become +)
echo urlencode('hello world & goodbye');
// hello+world+%26+goodbye

// rawurlencode β€” for path segments (spaces become %20)
echo rawurlencode('hello world & goodbye');
// hello%20world%20%26%20goodbye

Command Line (curl)

# curl automatically encodes with --data-urlencode
curl -G 'https://api.example.com/search' \
  --data-urlencode 'q=hello world & goodbye'

# Manual encoding with Python
echo -n 'hello world' | python3 -c "import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.read()))"

Unicode and International Characters

Non-ASCII characters (emoji, accented letters, CJK characters) are first encoded to UTF-8 bytes, then each byte is percent-encoded:

// The word "cafΓ©"
cafΓ© β†’ UTF-8 bytes: 63 61 66 C3 A9 β†’ caf%C3%A9

// Japanese "東京" (Tokyo)
東京 β†’ UTF-8: E6 9D B1 E4 BA AC β†’ %E6%9D%B1%E4%BA%AC

// Emoji "πŸš€"
πŸš€ β†’ UTF-8: F0 9F 9A 80 β†’ %F0%9F%9A%80

Common URL Encoding Mistakes

1. Double Encoding

Encoding an already-encoded string turns %20 into %2520. Always encode raw values, never encoded ones.

2. Encoding the Entire URL

Don't encode https:// or / separators. Only encode parameter values and path segments that contain special characters.

3. Forgetting to Encode + in Query Values

If your data literally contains a + sign (like "C++"), it must be encoded as %2B, or it will be interpreted as a space.

4. Not Encoding Ampersands in Values

If a parameter value contains &, it will be interpreted as a parameter separator unless encoded as %26.

πŸ”§ URL Encode & Decode Online

Quickly encode or decode URLs and query parameters. Handles Unicode, spaces, and all special characters.

Open URL Encoder β†’

Recommended Tools & Resources

Level up your workflow with these developer tools:

Try DigitalOcean → Insomnia API Client → HTTP: The Definitive Guide →

Dev Tools Digest

Get weekly developer tools, tips, and tutorials. Join our developer newsletter.

Frequently Asked Questions

Why can't URLs just support all characters?

URLs were designed in the early 1990s for ASCII-only systems. The character restrictions allow URLs to be transmitted reliably through any system β€” email, HTML attributes, command lines β€” without ambiguity. Percent encoding is the bridge between this ASCII-only world and modern Unicode text.

What's the difference between encodeURI and encodeURIComponent?

encodeURI() encodes a complete URL, preserving characters like :, /, ?, #. encodeURIComponent() encodes everything except unreserved characters β€” use it for individual parameter values.

Do I need to URL-encode JSON in query parameters?

Yes. JSON contains {, }, ", :, and other characters that must be encoded. Better yet, send JSON in the request body instead of query parameters.

Related reading: URL Encoder & Decoder Guide Β· Query String Parser & Builder

Frequently Asked Questions

Which characters need URL encoding?

Characters that must be encoded: spaces (%20), # (%23), % (%25), & (%26), + (%2B), = (%3D), and any non-ASCII characters. Safe characters that don't need encoding: A-Z, a-z, 0-9, and - _ . ~

Why does a space become %20 in URLs?

The % sign followed by two hex digits is URL encoding (percent-encoding). Space is ASCII character 32, which is 20 in hexadecimal, hence %20. In HTML forms, spaces may also be encoded as + signs.

How do I decode a URL-encoded string?

In JavaScript: decodeURIComponent('%48ello%20World'). In Python: urllib.parse.unquote(string). Or use our free tool at devtoolkit.cloud/tools/url-encoder to decode any URL-encoded string instantly.