What Is URL Encoding (Percent-Encoding)?

A URL can only safely carry a limited set of characters. Under the RFC 3986 standard, the characters that can be used directly in a URL are limited to English letters, digits and a few marks (- _ . ~); everything outside that — a space, non-ASCII letters (ü, ı, ş, ğ, ö, ç), signs such as &, = or %, or any Unicode character — cannot be placed safely inside a URL in raw form. A space in a query string can be confused with the & character that separates parameters, and a Unicode character may be interpreted differently by different systems.

URL encoding (percent-encoding) solves this problem: it converts every disallowed character into a hexadecimal code of the form %XX corresponding to that character's byte value. The URL then becomes text made up only of safe ASCII characters, interpreted the same way everywhere.

How Does Percent-Encoding Work?

Encoding works on the character's UTF-8 bytes. A character in the ASCII range (English letters, digits) is a single byte, so it becomes a single %XX group; the space character, for example, always becomes %20. A multi-byte UTF-8 character becomes more than one %XX group: the letter ü consists of two bytes in UTF-8, so it is encoded as %C3%BC.

RFC 3986 divides characters into two groups. Unreserved charactersA-Z a-z 0-9 - _ . ~ — are never encoded, because they carry no special meaning in a URL structure. Reserved characters, on the other hand, are the ones that define a URL's structure (protocol, path, query, fragment), such as : / ? # [ ] @ (general delimiters) and ! $ & ' ( ) * + , ; = (sub-delimiters); depending on the context, these are either left as they are or encoded.

Let's look at a concrete example. Running encodeURIComponent("merhaba dünya") — Turkish for "hello world" — gives merhaba%20d%C3%BCnya. The space is a single-byte character, so it becomes %20; the two-byte letter ü becomes %C3%BC, matching its C3 BC bytes in UTF-8. In the end only unreserved characters (letters, digits, - _ . ~) stay as they are; everything else is converted into a code beginning with a percent sign.

The Difference Between encodeURIComponent and encodeURI

JavaScript offers two different encoding functions, and they are not interchangeable. encodeURIComponent encodes every character except the unreserved ones (A-Z a-z 0-9 - _ . ~), including URL structural characters such as &, =, ? and /. This function is designed for encoding a single value to be placed into a query parameter or a path segment — for instance, by turning an & character in user input into %26, it prevents that character from being wrongly interpreted as a parameter separator.

encodeURI, by contrast, leaves the characters that make up a URL's structure (: / ? # [ ] @ ! $ & ' ( ) * + , ; =) untouched. This function is designed for encoding a complete URL that has already been assembled and whose structure must be preserved — for example a full URL to be pasted into the address bar or shared as a link.

Both functions turn a space into %20. There is one historical exception: in data sent by classic HTML forms with application/x-www-form-urlencoded, a space is encoded as a + sign rather than %20. That is a separate rule specific to form data, not output produced by encodeURIComponent or encodeURI.

Which One Should You Use When?

ScenarioFunction to useWhy
The value of a query parameter (e.g. a search term)<code>encodeURIComponent</code>Characters inside the value such as <code>&amp;</code>, <code>=</code> or a space are fully encoded so they cannot break the query structure
A complete URL that has already been assembled<code>encodeURI</code>The URL's structural characters such as <code>: / ?</code> are preserved, and only spaces and Unicode characters are encoded
Decoding an encoded URL<code>decodeURIComponent</code> / <code>decodeURI</code>Whichever function encoded it must be matched by its pair when decoding; otherwise some characters can be interpreted incorrectly

Common Mistakes

  • Encoding a complete URL with encodeURIComponent: the classic mistake. Structural characters such as : and / also turn into %3A / %2F, and what you are left with is no longer a valid URL but an opaque string. Always use encodeURI for a full URL and encodeURIComponent for a single value to be embedded inside a URL.
  • Double encoding: if you encode a string that already contains %20 with encodeURIComponent again, the % sign itself is also encoded and the result becomes a broken value such as %2520. Repeating the encode operation without checking whether a value has already been encoded ends in strange character sequences in the address bar or in API requests.
  • Not encoding query parameter values at all: adding text coming from a user straight into the query string (?q= + raw text) breaks the URL's other parameters or cuts the query short whenever the text contains &, # or a space. Every parameter value should be encoded separately with encodeURIComponent and only then joined with &.
  • Trying to decode broken percent-encoding: decodeURIComponent throws an error when it meets an invalid %XX sequence (for instance a half-finished %). In code that works with user input, this call needs to be wrapped in an error handling block.

The KEYDAL URL Encode / Decode Tool

If you are not sure whether you are encoding a value or a complete URL, seeing the difference on live examples is the fastest way to find out. KEYDAL's URL encode/decode tool lets you switch between component mode (encodeURIComponent) and full URL mode (encodeURI); it encodes or decodes the text you enter instantly, runs entirely in your browser and sends no data to any server.