URLs can only safely contain a limited set of characters. Anything outside that set — spaces, accented letters, emoji, or symbols that already have structural meaning in a URL — has to be represented differently, using a scheme called percent-encoding. That's where things like %20 come from.
What URL Encoding Actually Does
Percent-encoding replaces an unsafe character with a percent sign followed by its two-digit hexadecimal byte value. A space (byte value 32 in decimal, 20 in hex) becomes %20. An ampersand becomes %26. This lets any character — even ones outside the basic set URLs officially support — travel safely inside a URL without being confused for part of its structure.
Why Spaces Become %20 (or +)
You'll see spaces represented two different ways depending on context. %20 is the general percent-encoding for a space, valid anywhere in a URL. A plus sign (+) also represents a space, but only inside form-encoded query string data — a convention that dates back to how HTML forms originally submitted data. Outside a query string, a literal + means an actual plus character, not a space, which is why mixing up the two contexts is a common source of bugs.
encodeURIComponent vs. encodeURI
JavaScript provides two different encoding functions, and picking the wrong one is a frequent source of broken links:
- encodeURIComponent: Escapes nearly everything, including
/,?,&, and#. Use this when encoding a single piece of data — like a search term or a filename — that will be inserted into a URL. - encodeURI: Leaves structural characters like
/,?, and&untouched, since it assumes you're encoding a whole, already-valid URL and don't want to break its existing structure.
Using encodeURI on a single query parameter (instead of encodeURIComponent) is a classic bug — any & or = inside your actual data will be misread as a new parameter boundary instead of literal data.
Reserved and Unsafe Characters
Characters like &, =, ?, #, and / are called "reserved" because they already have specific structural meaning in a URL — separating the path from the query string, separating parameters, and so on. If actual data needs to contain one of these characters, it must be encoded, or a URL parser will misinterpret where the structure ends and the data begins.
Encoding or Decoding a URL
Rather than tracking which function or character set applies, paste text into our free URL Encoder/Decoder. It toggles between encodeURIComponent and encodeURI, switches between %20 and + for spaces, can process a batch of lines at once, and shows a live, character-by-character preview of exactly what's changing.
FAQ
Why do spaces in a URL sometimes show up as %20 and other times as a plus sign? Both represent an encoded space, but in different contexts. %20 is the standard percent-encoding used throughout a URL's path. A plus sign specifically represents a space only within a query string's form-encoded data (the part after the ?), a convention left over from HTML form submissions — it isn't valid as a space anywhere else in the URL.
What's the real difference between encodeURIComponent and encodeURI in JavaScript? encodeURIComponent escapes nearly every special character, including things like /, ?, and &, making it correct for encoding a single value — like a search term — that will be inserted into a URL. encodeURI leaves those structural characters alone because it assumes you're encoding a complete, already-structured URL and don't want to break its existing slashes or query separators.
Why can't URLs just contain spaces and special characters directly? Certain characters — spaces, &, ?, #, and others — already have structural meaning within a URL (separating the path from the query string, separating query parameters from each other, and so on). If those characters appeared unencoded inside actual data, like a search term, a parser couldn't tell whether they were part of the data or part of the URL's own structure. Percent-encoding sidesteps the ambiguity entirely.
Is URL encoding the same thing as encryption? No — URL encoding (percent-encoding) is fully reversible and provides no confidentiality whatsoever. Anyone can decode it instantly with no key required. It exists purely to make certain characters safe to transmit inside a URL, not to hide or protect the data in any way.