Skip to content
Encode & Decode 6 min read

URL Encoding Explained: Percent-Encoding for Web Developers

Learn why URLs need encoding, which characters require percent-encoding, the difference between encodeURI and encodeURIComponent in JavaScript, and common URL encoding mistakes.

ToolsVito Team

Why URLs Need Encoding

The URL specification (RFC 3986) defines a limited set of allowed characters. Characters outside this set — spaces, Unicode, special symbols — must be encoded as % followed by their two-digit hex value. This ensures URLs can be safely transmitted over systems that might otherwise misinterpret certain bytes.

Safe Characters (No Encoding Needed)

These characters are allowed in URLs without encoding:

  • Unreserved: A–Z a–z 0–9 - _ . ~
  • Reserved (structural): : / ? # [ ] @ ! $ & ' ( ) * + , ; = — these have special meaning in URL structure

Everything else must be percent-encoded.

Common Encodings

Space   → %20 (or + in query strings)
#       → %23
%       → %25
&       → %26
+       → %2B (when literal, not space in form data)
=       → %3D
?       → %3F
/       → %2F (when inside a path component)
@       → %40
€       → %E2%82%AC (UTF-8: E2 82 AC)
中      → %E4%B8%AD (UTF-8: E4 B8 AD)

encodeURI vs encodeURIComponent

JavaScript has two encoding functions with importantly different behavior:

// encodeURI — encodes a full URL
// Does NOT encode: : / ? # [ ] @ ! $ & ' ( ) * + , ; =
encodeURI("https://example.com/path?q=hello world&lang=en")
// "https://example.com/path?q=hello%20world&lang=en"

// encodeURIComponent — encodes a URL component (query value, path segment)
// DOES encode: : / ? # [ ] @ ! $ & ' ( ) * + , ; =
encodeURIComponent("hello world & more")
// "hello%20world%20%26%20more"

encodeURIComponent("https://example.com")
// "https%3A%2F%2Fexample.com"  ← / and : are encoded

When to Use Which

  • Use encodeURIComponent for individual query parameter names and values.
  • Use encodeURI only if you already have a full URL that you want to escape minimally.
  • Never use the deprecated escape() — it doesn't handle Unicode correctly.

Building URLs Safely

// Bad — manual string concatenation is a bug waiting to happen
const url = `/search?q=${userInput}&lang=en`;

// Good — URLSearchParams handles encoding automatically
const params = new URLSearchParams({ q: userInput, lang: "en" });
const url = `/search?${params}`;

// Also good — URL constructor
const url = new URL("https://api.example.com/search");
url.searchParams.set("q", userInput);
url.searchParams.set("lang", "en");
url.toString();

Decoding

decodeURIComponent("hello%20world%20%26%20more")
// "hello world & more"

// In Node.js
new URL("https://example.com/path?q=hello%20world").searchParams.get("q")
// "hello world"

The + vs %20 Difference

In HTML form submissions with application/x-www-form-urlencoded encoding, spaces are encoded as +. In URLs, spaces should be %20. The two are different contexts:

  • Query string from HTML form: ?q=hello+world
  • Manually constructed URL: ?q=hello%20world

Most URL parsers treat both as spaces in query strings, but be consistent within your codebase.

Encode and Decode URLs Instantly

Use ToolsVito's URL Encoder/Decoder to encode or decode any URL or component, with support for full URL and component-level encoding — directly in your browser.

Try it now — free, runs in your browser

URL Encode / Decode

Escape & unescape URLs