URL Encoding Explained: When and Why You Need It

Understand URL encoding, percent-encoding, why spaces become %20, and when to encode your URLs. Includes practical examples in JavaScript, Python, and bash.

Try it yourself

Use our free URL Encoder — no sign-up, runs in your browser.

Open tool →

URLs have a specific format. Certain characters are reserved for special meaning - slashes separate paths, question marks introduce query parameters, ampersands separate parameters. But what happens when your data contains these characters? Or spaces? That’s where URL encoding comes in.

Why URL encoding exists

URLs can only contain a limited set of characters safely. Reserved characters like ?, &, #, and spaces need special handling.

Compare these:

// Regular text
search for: "hello world"

// In a URL query string (wrong)
https://example.com/search?q=hello world
// Problem: spaces break the URL

// In a URL query string (correct)
https://example.com/search?q=hello%20world
// Works: %20 represents a space

The browser interprets the first URL incorrectly. The second one works because spaces are “percent-encoded” as %20.

What is percent-encoding?

Percent-encoding (also called URL encoding) converts characters to a % followed by two hexadecimal digits.

CharacterEncodedHex Value
space%200x20
!%210x21
#%230x23
$%240x24
&%260x26
?%3F0x3F
=%3D0x3D

The hexadecimal value maps to the character’s ASCII code. Space (ASCII 32) is 0x20 in hex, so it encodes as %20.

When to encode URLs

You need to encode:

  • Query string parameters (the value part after ?)
  • Path segments containing special characters
  • Form data in request bodies

You don’t encode:

  • The protocol (https://)
  • The domain name
  • The forward slashes separating path segments (unless they’re in data)
https://example.com/search?q=hello%20world&filter=active
└─────┬─────┘       └───┬──┘    └───────────────────┬──────────────┘
Protocol & domain   Path      Query string (encoded)

Encoded:     query value and parameter names
Not encoded: scheme, domain, path slashes

Reserved characters that need encoding

These characters have special meaning in URLs and must be encoded in certain contexts:

: / ? # [ ] @ ! $ & ' ( ) * + , ; = %

For example:

  • & separates query parameters, so if your data contains &, encode it as %26
  • = separates parameter names from values, so if your value contains =, encode it as %3D
  • # starts a fragment, so if your data contains #, encode it as %23

Encoding in JavaScript

Use encodeURIComponent() for query string values and encodeURI() for full URLs:

// Encoding a query parameter value
const userInput = "John Doe & Friends";
const encoded = encodeURIComponent(userInput);
console.log(encoded);
// Output: John%20Doe%20%26%20Friends

// Building a query string
const name = "Product & Services";
const query = `?q=${encodeURIComponent(name)}`;
console.log(query);
// Output: ?q=Product%20%26%20Services

// Decoding
const decoded = decodeURIComponent("John%20Doe%20%26%20Friends");
console.log(decoded);
// Output: John Doe & Friends

Use encodeURIComponent() for:

  • Query parameter values
  • Form field values
  • Anything that’s data, not structure

Use encodeURI() sparingly - it encodes less aggressively and is meant for full URLs, not individual values.

Encoding in Python

from urllib.parse import quote, unquote, urlencode

# Encode a single string
text = "hello world & friends"
encoded = quote(text)
print(encoded)
# Output: hello%20world%20%26%20friends

# Decode
decoded = unquote(encoded)
print(decoded)
# Output: hello world & friends

# Encode query parameters (recommended)
params = {"q": "hello world", "filter": "active"}
query_string = urlencode(params)
print(query_string)
# Output: q=hello+world&filter=active

# Build full URL
from urllib.parse import urljoin
base = "https://example.com/search?"
url = base + query_string
print(url)
# Output: https://example.com/search?q=hello+world&filter=active

Encoding in Bash

# Using printf and sed
text="hello world & friends"
encoded=$(printf %s "$text" | sed 's/ /%20/g' | sed 's/&/%26/g')
echo $encoded
# Output: hello%20world%20%26%20friends

# Better: use a loop for all special characters
urlencode() {
  local string="${1}"
  printf %s "$string" | jq -sRr @uri
}

urlencode "hello world & friends"
# Output: hello%20world%20%26%20friends

Common encoding gotchas

Space encoding: %20 vs +

In query strings, space can be encoded as %20 (percent-encoded) or + (form-encoded). Both mean the same thing.

https://example.com/search?q=hello%20world  ✅
https://example.com/search?q=hello+world    ✅ (form-encoded, common in forms)

Use %20 in path segments and when you want to be explicit. Use + in form submissions (browsers do this automatically).

Encoding & - a common mistake

If your parameter value contains &, you must encode it as %26:

// Wrong - parsed as two parameters
?q=fish & chips

// Correct - parsed as one parameter with value "fish & chips"
?q=fish%20%26%20chips

Double-encoding (a security issue)

Don’t encode twice. This is a common bug:

// Wrong - double-encoded
const value = "hello world";
const encoded1 = encodeURIComponent(value);     // "hello%20world"
const encoded2 = encodeURIComponent(encoded1);  // "hello%2520world"
// %2520 = %25 + "20", where %25 is the % character itself

// Right - encode once
const encoded = encodeURIComponent(value);

When does the browser auto-encode?

Modern browsers auto-encode spaces in URL bars (you can type spaces, they become %20). But programmatically, always encode explicitly - don’t rely on auto-encoding.

Decode URLs and check your work

Use our free URL Encoder to encode and decode URLs online. Paste a URL or text and see exactly what gets encoded and why - helpful for debugging API calls and query strings.

Summary

  • Encode query string values, path data, and form data using encodeURIComponent() (JavaScript) or quote() (Python)
  • Don’t encode the scheme, domain, or path slashes
  • Reserved characters (&, ?, #, =, %, etc.) must be encoded in data values
  • Space encodes as %20 (or + in forms)
  • Never double-encode - encode once and use the result
  • Test your URLs with a URL encoder tool to catch mistakes early

Ready to try it?

Free, client-side URL Encoder — nothing sent to a server.

Open URL Encoder →