0 characters

0 characters

0 characters

0 characters

About URL Encoding

URLs are formally restricted to a small set of characters: the ASCII letters A–Z, a–z, the digits 0–9, and a handful of symbols defined as “unreserved” by RFC 3986. Anything else — spaces, accented characters, emoji, control characters, Chinese, Arabic — must be percent-encoded: each non-ASCII byte is replaced by a percent sign followed by two hex digits. The string hello world becomes hello%20world; the em dash (Unicode code point U+2014, encoded as the three bytes E2 80 94 in UTF-8) becomes %E2%80%94.

This matters because URLs travel through systems that cannot safely carry raw binary data: mail servers may strip high bytes, log analyzers may choke on non-ASCII, and proxies have historically mangled URLs with special characters. Percent-encoding sidesteps all of these by restricting the URL to a guaranteed-safe alphabet. The trade-off is human readability: a URL with many query parameters quickly becomes a wall of percent signs that nobody can parse visually.

Two Encoding Modes

JavaScript exposes two encoders, and they differ in which characters they leave untouched:

  • encodeURIComponent — leaves the JavaScript-defined safe set (A-Z a-z 0-9 - _ . ! ~ * ' ( )) and percent-encodes other characters. RFC 3986’s formal unreserved set is narrower because it does not include ! ' ( ) *. Use this mode for query parameter values and path segments when you need browser-compatible JavaScript output.
  • encodeURI — additionally preserves URL-structural characters (; / ? : @ & = + $ , #). Use this when you have a full URL string and want to preserve its structure while encoding spaces and Unicode characters.

The wrong choice is a common source of bugs. Encoding a complete URL with encodeURIComponent turns the colons and slashes into %3A and %2F, breaking the URL. Encoding a query value with encodeURI leaves the ampersand intact, which the server then misinterprets as a parameter separator.

Form Encoding (application/x-www-form-urlencoded)

HTML form submissions use a related encoding where the space becomes + instead of %20, and the parameters are joined with &. The URLSearchParams API in JavaScript handles this correctly. If you are building a URL with multiple form-style parameters, the easiest approach is:

const params = new URLSearchParams({ q: 'hello world', lang: 'en' });
const url = 'https://example.com/search?' + params.toString();
// => "https://example.com/search?q=hello+world&lang=en"

This tool uses encodeURIComponent internally, which produces hello%20world rather than hello+world. Both are valid percent-encoded representations; the decoded value is identical. If you need the + form, post-process the output by replacing %20 with +.

Common Use Cases

  • Debugging a broken URL: “Why does this link 404?” Decode the URL and look for unintended %2F, missing characters, or accidental double-encoding.
  • Building API call URLs: Encode each query parameter value with encodeURIComponent before joining the URL. Avoid concatenating user input into a URL string without encoding.
  • Sharing non-ASCII URLs: Some chat and email clients break URLs containing Unicode. Percent-encoding makes them portable.
  • Working with form data: When debugging form submissions, copy the encoded body and decode it locally to see what the server actually receives.

Why Servers Fix This for You

Modern web frameworks (Express, Django, Rails, Spring) automatically decode query parameters and form bodies before your application code sees them. The raw q=hello%20world arrives as the decoded string hello world. This is why most developers are surprised to learn that percent-encoding exists at all — the framework handling hides it. The encoding still matters when you construct URLs yourself, when you read raw bytes from a network tool, or when you debug a misconfigured server that fails to decode.

Frequently Asked Questions

Why is space encoded as %20 and not as a literal space?

URLs cannot contain literal spaces because spaces are not in the allowed grammar (RFC 3986 lists them as “not recommended” and most parsers reject them outright). %20 is the percent-encoded representation of the ASCII space byte (0x20). HTML form submissions use + instead of %20 for spaces, but both decode to the same value.

Is %20 in a URL the same as a literal space?

Yes when the URL is parsed. Browsers and servers treat %20 as a space for display and processing purposes. The encoded form is just the safe transport representation; the decoded form is the same character. The URL https://example.com/hello%20world shows “hello world” in the address bar and requests the same resource as https://example.com/hello world would (if the latter were allowed).

Why does percent-encoding use uppercase hex (E2, 80, 94) and not lowercase (e2, 80, 94)?

Both are valid and equivalent. RFC 3986 calls for uppercase hex digits as a convention, but parsers must accept both. This tool emits uppercase to match the convention.

How does Unicode work in URLs?

Unicode characters are first encoded as UTF-8 bytes, then each byte is percent-encoded. The em dash (U+2014) is three bytes in UTF-8 (E2 80 94) and becomes %E2%80%94 in a URL. ASCII characters in the source have a single-byte UTF-8 representation and percent-encode the same way as before.

Why is my decoded URL still showing percent signs?

Double-encoding. Some systems percent-encode an already-encoded URL, producing hello%2520world. Decoding once yields hello%20world; decoding again yields hello world. Most modern tools handle this correctly; if you see it, the upstream system is misconfigured.