FmtDev
Language
Back to blog
March 25, 2026

URL Encoding Explained: Why %20 Means Space

Understand how URL encoding works, why special characters need to be encoded, and what %20, %3A, %2F and other percent-encoded values actually mean. A practical guide for developers.

What Is URL Encoding?

Every time you see %20 in a URL, you are looking at URL encoding in action.

URL encoding (also called percent encoding) is the process of converting characters that are not allowed in URLs into a format that can be safely transmitted. It replaces unsafe characters with a % sign followed by two hexadecimal digits representing the character's ASCII code.

For example:

  • A space becomes %20
  • An @ sign becomes %40
  • A # hash becomes %23
  • A / slash becomes %2F

This is why a Google search for "hello world" produces a URL like:

https://www.google.com/search?q=hello%20world

The space between "hello" and "world" cannot exist in a URL, so it gets encoded as %20.

Why URLs Need Encoding

URLs have strict rules about which characters are allowed. These rules come from RFC 3986, the official specification for URI syntax.

Safe Characters (No Encoding Needed)

These characters can appear in URLs without encoding:

A-Z  a-z  0-9
-  _  .  ~

Letters, numbers, hyphens, underscores, dots, and tildes are always safe.

Reserved Characters (Must Be Encoded When Used As Data)

These characters have special meaning in URLs:

| Character | Meaning | Encoded | |---|---|---| | / | Path separator | %2F | | ? | Query string start | %3F | | & | Parameter separator | %26 | | = | Key-value separator | %3D | | # | Fragment identifier | %23 | | @ | User info separator | %40 | | : | Port separator | %3A | | + | Space (in forms) | %2B |

When these characters appear as data (not as structural elements), they must be encoded.

For example, if a search query contains &, it must be encoded:

# Wrong — the & breaks the query string
?search=Tom & Jerry&page=1

# Correct — the & in the search term is encoded
?search=Tom%20%26%20Jerry&page=1

Unsafe Characters (Always Encode)

These characters are never safe in URLs:

space  "  <  >  {  }  |  \  ^  `

They must always be percent-encoded.

Common Encodings You Will See

| Character | Encoded | You See This In | |---|---|---| | Space | %20 or + | Search queries, file names | | @ | %40 | Email addresses in URLs | | # | %23 | Hashtags, anchor references | | & | %26 | Search terms containing "and" | | = | %3D | Values containing equals signs | | / | %2F | File paths in query parameters | | ? | %3F | Questions in search queries | | % | %25 | The percent sign itself | | + | %2B | Plus signs in phone numbers | | é | %C3%A9 | French/accented characters | | | %E6%97%A5 | CJK characters (UTF-8) |

Space: %20 vs +

There are two ways to encode a space in a URL:

  • %20 — used in URL paths and modern encoding
  • + — used in HTML form submissions (application/x-www-form-urlencoded)

Both represent a space, but they are used in different contexts:

URL path:      /my%20file.pdf         ← %20
Query string:  ?name=John+Doe         ← + (form encoding)
Query string:  ?name=John%20Doe       ← %20 (also valid)

When decoding, your parser needs to handle both formats.

URL Encoding in JavaScript

Encoding

JavaScript provides two functions:

// encodeURIComponent — encodes everything except A-Z a-z 0-9 - _ . ~
encodeURIComponent("hello world & goodbye")
// → "hello%20world%20%26%20goodbye"

// encodeURI — encodes but preserves URL-structural characters
encodeURI("https://example.com/path?q=hello world")
// → "https://example.com/path?q=hello%20world"

Rule: Use encodeURIComponent() for query parameter values. Use encodeURI() for full URLs.

Decoding

decodeURIComponent("hello%20world%20%26%20goodbye")
// → "hello world & goodbye"

decodeURI("https://example.com/path?q=hello%20world")
// → "https://example.com/path?q=hello world"

URL Encoding in Python

from urllib.parse import quote, unquote

# Encoding
quote("hello world & goodbye")
# → "hello%20world%20%26%20goodbye"

# Decoding
unquote("hello%20world%20%26%20goodbye")
# → "hello world & goodbye"

Common Mistakes

1. Double Encoding

If you encode a string that is already encoded, you get double encoding:

Original:        hello world
First encoding:  hello%20world
Double encoding: hello%2520world  ← %25 is the encoding of %

%2520 means the % in %20 was encoded again. This is a very common bug that breaks URLs silently.

2. Encoding the Entire URL

// Wrong — encodes the :// and / too
encodeURIComponent("https://example.com/path")
// → "https%3A%2F%2Fexample.com%2Fpath"

// Right — only encode parameter values
const base = "https://example.com/search";
const query = encodeURIComponent("hello world");
const url = `${base}?q=${query}`;
// → "https://example.com/search?q=hello%20world"

3. Forgetting to Decode

When reading URL parameters, always decode them:

// URL: ?name=John%20Doe
const params = new URLSearchParams(window.location.search);
const name = params.get('name');
// → "John Doe" (automatically decoded)

URLSearchParams handles decoding automatically. If you parse query strings manually, you need to call decodeURIComponent() yourself.

4. Not Encoding User Input

If you build URLs from user input without encoding, special characters can break the URL or create security vulnerabilities:

// Dangerous — user input could contain & or = or other special characters
const url = `/search?q=${userInput}`;

// Safe
const url = `/search?q=${encodeURIComponent(userInput)}`;

This is especially important for preventing injection attacks.

UTF-8 and International Characters

Modern URLs support international characters through UTF-8 encoding:

é → %C3%A9 (2 bytes in UTF-8)
ñ → %C3%B1 (2 bytes in UTF-8)
日 → %E6%97%A5 (3 bytes in UTF-8)
😀 → %F0%9F%98%80 (4 bytes in UTF-8)

Each byte of the UTF-8 representation is individually percent-encoded. This is why non-ASCII characters produce long encoded strings.

Modern browsers display international characters in the address bar but send them encoded over the network.

Decoding URLs Safely

When working with URLs that contain sensitive data (API endpoints, internal paths, authentication parameters), be careful about where you decode them.

Online URL decoders process your data on their servers. If your URL contains internal API paths, authentication tokens, or sensitive query parameters, you are exposing that information to a third party.

Use a decoder that runs entirely in your browser. No data should leave your machine.

The FmtDev URL Decoder processes everything locally. Your URLs never leave your browser.

Key Takeaways

  1. URL encoding replaces unsafe characters with % followed by hex values
  2. Spaces become %20 in URLs and + in form submissions
  3. Use encodeURIComponent() for parameter values, encodeURI() for full URLs
  4. Watch out for double encoding — it breaks URLs silently
  5. Always encode user input before putting it in URLs
  6. International characters are encoded as multi-byte UTF-8 sequences
  7. For sensitive URLs, decode locally — never use online tools

Related Articles

Related Tool

Ready to use the Free Online Base64 Encoder & Decoder tool? All execution is 100% local.

Open Free Online Base64 Encoder & Decoder