URL Encoding Explained: Percent Encoding in Practice

BY TOOLS.FUN  ·  MARCH 28, 2026  ·  6 min read

Every developer has encountered a URL that looks like https://example.com/search?q=hello%20world&lang=en and wondered what the %20 means. That's URL encoding — also called percent encoding — and understanding it prevents a class of bugs that appear in form submissions, API calls, redirects, and web scraping code.

Related tools: use our Base64 Encoder for Base64-in-URL scenarios, Unicode Converter to inspect non-ASCII characters before encoding, and RegExp Tester to build URL validation patterns.

What is URL Encoding?

URLs can only contain a limited set of ASCII characters. Many characters that appear in real-world data — spaces, Unicode characters, punctuation — are either forbidden in URLs or have special meaning that would conflict with URL parsing. URL encoding converts these characters into a format that is safe for use in a URL by representing them as a percent sign followed by two hexadecimal digits: %XX.

The specification is defined in RFC 3986. Every character in a URL must either be an unreserved character (which can be used as-is) or must be percent-encoded.

Reserved vs Unreserved Characters

Unreserved characters can always appear in a URL without encoding:

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

Reserved characters have special meaning in URL syntax and can only appear unencoded in specific positions. If they appear in data (not as structural delimiters), they must be encoded:

:  /  ?  #  [  ]  @  !  $  &  '  (  )  *  +  ,  ;  =

All other characters — including spaces, Unicode characters, and most punctuation — must be percent-encoded.

Key point: The space character is represented as %20 in URLs. In HTML form data (application/x-www-form-urlencoded), spaces are encoded as +. These are different encodings and should not be mixed up.

How Percent Encoding Works

To percent-encode a character:

  1. Convert the character to its UTF-8 byte sequence.
  2. Express each byte as two uppercase hexadecimal digits preceded by %.
space   → %20   (0x20 in ASCII/UTF-8)
!       → %21
"       → %22
#       → %23
$       → %24
&       → %26
/       → %2F
:       → %3A
?       → %3F
@       → %40
é       → %C3%A9  (two bytes: 0xC3 0xA9 in UTF-8)

Note that multi-byte UTF-8 characters produce multiple %XX sequences. The accented character é requires two bytes in UTF-8, so it becomes %C3%A9.

Query Strings vs Path Segments

The rules for URL encoding differ slightly between URL components:

Path segments — the slashes in a URL path are structural, so a / inside a path segment value must be encoded as %2F. Other special characters that aren't reserved in path syntax can often appear unencoded.

Query strings — the part after the ?. Keys and values are separated by = and pairs are separated by &. Any ?, =, or & appearing inside a value must be encoded. Spaces in query strings are often encoded as + by browsers for historical reasons.

# Correct: value with & encoded
https://example.com/search?q=cats+%26+dogs

# Incorrect: unencoded & breaks query parsing
https://example.com/search?q=cats+&+dogs
Key point: When building URLs programmatically, always use your language's built-in URL encoding functions rather than constructing URLs by string concatenation. In JavaScript use encodeURIComponent(), in Python use urllib.parse.quote(), in Java use URLEncoder.encode().

Common Characters and Their Encodings

space  %20      !  %21      "  %22      #  %23
$      %24      %  %25      &  %26      '  %27
(      %28      )  %29      *  %2A      +  %2B
,      %2C      /  %2F      :  %3A      ;  %3B
=      %3D      ?  %3F      @  %40      [  %5B
]      %5D

Double Encoding Pitfalls

Double encoding happens when already-encoded data gets encoded a second time. A URL like /files/my%20document.pdf contains a correctly encoded space. If a framework re-encodes the path, the % sign gets encoded to %25, producing /files/my%2520document.pdf — which will 404 because the server is looking for a file named literally "my%20document.pdf".

This commonly occurs when passing encoded URLs as query parameter values: the outer URL needs to encode the inner URL's special characters, so a URL-within-a-URL should be encoded with encodeURIComponent() which encodes % signs too.

Key point: If you see %25 in a URL where you expected a literal %, you have a double-encoding bug. The %25 sequence decodes to %, which means the original encoding was encoded again.

URL Encoding vs Form Encoding

application/x-www-form-urlencoded is the format used when HTML forms are submitted with method="POST" and no enctype set. It is similar to URL query string encoding but with one key difference: spaces are encoded as + rather than %20. This is a legacy behaviour inherited from pre-RFC conventions.

When parsing form data on the server, ensure your parser handles the +-as-space convention. When encoding form data in JavaScript's fetch API, use the URLSearchParams class rather than constructing the body manually.

Encode and Decode URLs Online

The URL Encoder / Decoder at Tools.Fun lets you encode or decode any string for use in URLs. Paste a URL with special characters to encode it, or paste an encoded URL to see the human-readable form. Supports both standard percent encoding and form encoding modes.

← Back