CodeToolProCodeToolPro
GitHub
Encoders / Decoders·7 min read

URL Encoder Guide: Encode, Decode & Avoid Common Errors

CodeToolPro Team·

URL Encoder Guide: Encode, Decode & Avoid Common Errors

When you paste a string containing spaces, &, or = into a query parameter, things break. Those characters have special meaning in a URL, so they have to be escaped before they can travel safely. A URL encoder (also called a percent-encoder) turns unsafe characters into their %XX byte representation so the data survives the round trip. Try it instantly with our URL Encoder / Decoder — it runs entirely in your browser, so nothing you type is ever sent to a server.

This guide explains what URL encoding actually does, which characters must be escaped, how the algorithm differs across languages, the mistakes that silently corrupt data, and when reaching for a tool beats writing code.

What Is a URL Encoder?

A URL encoder applies percent-encoding (defined in RFC 3986) to a string. Every character that is not in a fixed "safe" set is replaced by a % followed by two hexadecimal digits that represent that character's byte value in UTF-8. A space becomes %20, a literal # becomes %23, and an emoji is encoded as a sequence of several %XX triplets.

The goal is simple: keep a URL a valid URL. Reserved characters such as ?, &, =, /, and # control how a URL is parsed. If your data contains one of them, the server will mistake your payload for syntax. Encoding neutralizes the ambiguity.

Reserved vs Unreserved Characters

RFC 3986 splits characters into two buckets:

ClassCharactersMust encode in data?
UnreservedA-Z a-z 0-9 - _ . ~No
Reserved (sub-delims)! * ' ( ) ; : @ & = + $ ,Yes
Reserved (gen-delims)/ ? # [ ] @Yes

A character only needs encoding when it appears as data rather than as URL syntax. The same / that separates path segments must stay literal in the path but be encoded as %2F if it is part of a filename you are transmitting.

Notice that ~, -, _, and . are deliberately left unreserved — they are safe to use verbatim.

How Encoding Handles Non-ASCII Text

ASCII characters map one byte to one %XX. But most real-world text is Unicode. The correct approach (what modern browsers and the URL standard use) is:

  1. Encode the character as UTF-8 (one to four bytes).
  2. Percent-encode each byte separately.

So é (U+00E9) → UTF-8 bytes 0xC3 0xA9%C3%A9. A naive encoder that percent-encodes the UTF-16 code unit instead produces the wrong value, and historically some systems encoded Latin-1 (ISO-8859-1), turning é into %E9. That mismatch is exactly why "it works in my browser but not on the server" bugs appear.

Code Examples

JavaScript

// Encode a full component (handles UTF-8 correctly)
const value = "hello world & friends 🚀";
const encoded = encodeURIComponent(value);
// "hello%20world%20%26%20friends%20%F0%9F%9A%80"

// Decode it back
console.log(decodeURIComponent(encoded));
// "hello world & friends 🚀"

// NOTE: encodeURI() is NOT for query values — it leaves ? & = / alone.

encodeURIComponent is almost always what you want for form fields and query values. Use the bare encodeURI only for whole-URL escaping, never for individual parameters.

Python

from urllib.parse import quote, unquote, quote_plus

value = "hello world & friends 🚀"

# quote() keeps spaces as %20
print(quote(value))          # hello%20world%20%26%20friends%20%F0%9F%9A%80

# quote_plus() turns spaces into + (old form-encoding style)
print(quote_plus(value))     # hello+world+%26+friends+%F0%9F%9A%80

print(unquote(quote(value))) # hello world & friends 🚀

quote_plus matches the legacy application/x-www-form-urlencoded convention where spaces become +. Mixing quote and quote_plus between client and server is a classic source of mismatches.

Common Mistakes

  • Encoding the whole URL instead of a component. Running encodeURIComponent on https://x.com/a?b=1 turns the slashes and ? into garbage. Encode each value, then assemble the URL.
  • Double encoding. Encoding an already-encoded string (%%25) produces %2520, which decodes to %20 instead of a space. Validate before encoding.
  • Using + where %20 is expected (or vice versa). The quote_plus vs quote difference, and server parsers that only accept %20, are a frequent mismatch.
  • Forgetting UTF-8. Older stacks encode Latin-1, so non-ASCII data corrupts across the boundary.
  • Encoding reserved characters you actually meant as syntax. If ? is your query separator, do not percent-encode it.

Related Tools

When to Use This Tool Instead of Code

Writing encodeURIComponent is one line, so why open a tool? For the same reason you use a JSON formatter: when you are debugging a request, reading a log, or copying a link into a ticket, you want to see the encoded and decoded form side by side, instantly, with no project, no dependency, and no paste of potentially sensitive data to a server. For application code, keep encodeURIComponent / quote in your codebase; for ad-hoc inspection and quick round-trips, the browser tool is faster and removes the "did I double-encode?" guesswork.