All posts
Tutorials 3 min read

URL Encoding: Why %20 Is a Space and Other Essentials

Learn how URL encoding works, why special characters need percent-encoding, and how to encode correctly in JavaScript, Python, and more.

Bilal jmal
Author

You’ve seen %20 in URLs and wondered what it means. Or your API request failed because an & in a parameter value broke the query string. URL encoding — also called percent encoding — is one of those fundamentals that causes constant bugs when misunderstood. This guide covers everything you actually need to know.

Why URLs Need Encoding

URLs can only contain a specific set of ASCII characters. Characters outside this set — spaces, symbols, non-Latin letters — must be encoded before they can appear in a URL. Without encoding, a space in a URL breaks the request, and a & in a parameter value gets parsed as a parameter separator.

The safe characters that don’t need encoding: A–Z a–z 0–9 - _ . ~

Everything else — including spaces, &, =, ?, /, #, and non-ASCII characters — must be percent-encoded when used in a query parameter value.

How Percent Encoding Works

Each unsafe character is replaced by a % followed by its two-digit hexadecimal ASCII (or UTF-8) code:

  • Space → %20 (or + in form data)
  • &%26
  • =%3D
  • +%2B
  • /%2F
  • ?%3F
  • #%23
  • @%40

You can encode and decode any string instantly with our URL Encoder tool.

encodeURI vs encodeURIComponent — The Critical Difference

This is where most bugs happen. JavaScript gives you two functions, and choosing the wrong one breaks things:

  • encodeURI(url) — encodes a complete URL. Leaves :// ? & = # / untouched because they’re structural parts of the URL.
  • encodeURIComponent(value) — encodes a single value. Encodes everything including & = ? / — use this for query parameter values.
// Wrong — & in value breaks the query string
const url = `https://api.example.com/search?q=${userInput}`

// Correct — encode the value, not the full URL
const url = `https://api.example.com/search?q=${encodeURIComponent(userInput)}`

URL Encoding in Other Languages

# Python
from urllib.parse import quote, urlencode
quote(string)                    # encodes a path segment
quote(string, safe='')           # encodes everything (like encodeURIComponent)
urlencode({'key': 'value with spaces & symbols'})  # encodes a dict as query string

# PHP
urlencode($string)      # encodes for query strings (spaces as +)
rawurlencode($string)   # RFC 3986 encoding (spaces as %20)

# curl (command line)
curl -G "https://api.example.com" --data-urlencode "q=hello world & more"

Common URL Encoding Bugs

  1. Double-encoding — encoding an already-encoded string turns %20 into %2520. Always decode first, then re-encode if needed.
  2. Encoding the whole URL — encoding https:// produces https%3A%2F%2F which breaks the request. Only encode parameter values.
  3. Forgetting non-ASCII characters — emoji and accented characters must be UTF-8 encoded then percent-encoded. é becomes %C3%A9.
  4. Using + for spaces outside forms+ means space only in application/x-www-form-urlencoded content type. In path segments, use %20.

Frequently Asked Questions

What is the difference between %20 and + for spaces?

%20 is the RFC 3986 standard encoding for a space in any part of a URL. + represents a space only in HTML form data (application/x-www-form-urlencoded). Use %20 for path segments and when in doubt; use + only for form-encoded query strings.

Why do some URLs work with spaces in them?

Browsers are lenient — they automatically encode spaces in URLs you type in the address bar. But this is browser behavior, not the URL spec. Code that constructs URLs must always encode explicitly; relying on browser tolerance breaks in APIs, curl, and server-side code.

How do I decode a URL-encoded string?

In JavaScript: decodeURIComponent(encoded). In Python: from urllib.parse import unquote; unquote(encoded). Or paste it into our URL Encoder / Decoder for an instant result.

Are URLs case-sensitive?

The host portion (example.com) is case-insensitive. The path, query string, and fragment are case-sensitive on most servers. Percent-encoded hex digits are case-insensitive — %2F and %2f are equivalent, but it’s best practice to use uppercase.

All posts
Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *