X Xerobit

URL Encoder / Decoder

Percent-encode URLs and query-string values, or decode them back. Four variants cover every real-world case: query values, full URLs, strict RFC 3986, and application/x-www-form-urlencoded form data.

encodeURIComponent (default) = safe for query values (encodes / : ? # & = +). encodeURI = safe for whole URLs (leaves / : ? # & = alone). RFC 3986 = strictest, also encodes ! * ' ( ). form = + for space instead of %20.

Live Market Insight

Source: DataForSEO · Updated 2026-04-25
Monthly searches (US)
22,200
keyword: "url encoder"
Keyword CPC
$18.56
highest CPC of launch set
Cluster size
4 keywords
encoder + decoder + online + encode
Top competitor
meyerweb.com
4/10 SERPs

How to use the URL encoder / decoder

  1. Pick a mode — Encode or Decode.
  2. Pick a variant that matches your target: query value, full URL, RFC 3986 strict, or form data.
  3. Paste into the left textbox. Processing runs automatically after 150ms.
  4. Click Copy to copy the output. Swap moves the output back into the input and flips the mode for round-trip checks.

Which variant should I use?

This is the question that trips up 90% of developers — and picking the wrong variant causes half the "mystery" URL bugs in production.

encodeURIComponent (default) — for a single value

Use this when you're encoding a value that will be placed inside a URL — a query-string value, a path segment, or a header. It encodes every character that has special meaning in URLs (/ : ? # & = +), which is exactly what you want for a value. This is the right default almost always.

const params = new URLSearchParams();
params.set('q', userInput);
fetch('/search?' + params);  // URLSearchParams does encodeURIComponent for you

encodeURI — for an entire URL

Use this when you have a full URL and want to escape only the truly illegal characters (spaces, non-ASCII) while leaving the URL structure (/, ?, #, &, =) intact. Rare — most of the time you're building URLs from parts, not escaping whole URLs. If you're tempted to use this to encode a query value, you're almost certainly wrong.

RFC 3986 strict

Stricter than encodeURIComponent. Also encodes !, *, ', (, ) — characters RFC 3986 marks as "sub-delims" that some parsers treat as special. Use this when you need maximum compatibility with strict URI parsers (some older OAuth flows, some XML-based APIs).

application/x-www-form-urlencoded

Used in HTML <form> submissions with method="POST" and the default enctype. The one meaningful difference from encodeURIComponent: spaces become + instead of %20. If you're building form bodies manually (no URLSearchParams), use this. In decoder mode, this option treats + as space.

What does percent-encoding actually do?

Every character becomes %XX where XX is the hex value of its UTF-8 byte(s). ASCII characters below 128 take one byte (e.g., space = %20). Non-ASCII characters take 2–4 bytes (e.g., é = %C3%A9, the UTF-8 bytes of U+00E9).

The set of characters that get encoded depends on the variant — that's all the variants do differently. The encoding math is identical; the "character allowlist" is what changes.

Common URL encoding bugs

Double-encoding

The most common bug. Something encodes once, then a middleware or framework encodes the output again. Result: %20 becomes %2520, and the %20 decoded once says "20" instead of a space. If you see %25 pairs mysteriously appearing, you're double-encoding.

Using encodeURI for a query value

encodeURI("a&b=c") returns a&b=c unchanged — because & and = are "valid" in a URL. Your server then parses two query params (a and b) instead of one. Use encodeURIComponent for values, always.

Plus becomes space (or doesn't)

In the query string of a URL, + is a literal plus sign. But in an application/x-www-form-urlencoded body, + is a space. Servers treat them differently depending on whether they're parsing the URL or the body. This is why you see PHP's urldecode (form style) vs rawurldecode (URL style).

Forgetting to encode the fragment

Everything after # in a URL is the fragment. Browsers encode fragments differently from query strings — ? and & are allowed unescaped, but # itself must be encoded. Get this wrong and deep-linked SPAs with # in state break.

Frequently asked questions

Why are some characters never encoded?

RFC 3986 defines "unreserved" characters that always stay literal: A-Z, a-z, 0-9, -, _, ., and ~. These are safe in every URL context, so no encoder touches them. Everything else depends on context (and the variant).

Is %20 and + the same thing?

Yes and no. In query strings, %20 = space and + = literal plus. In form bodies, + = space and %2B = literal plus. Don't assume — match your encoder to your consumer.

Does this tool handle non-ASCII correctly?

Yes. The tool uses JavaScript's native encodeURIComponent / decodeURIComponent, which always use UTF-8. You can paste CJK, emoji, or any Unicode and the encoded output is valid percent-encoded UTF-8.

Why did my decode fail with "URI malformed"?

You have an invalid escape sequence somewhere. Usual cause: an unescaped % character that isn't followed by two hex digits. Escape literal % as %25.

Is there a difference in what servers accept?

Almost none for the ASCII part — servers respect RFC 3986. The edge cases are mostly in how they parse form bodies vs query strings, and in how they handle +. Test both sides of your boundary.

Related tools

Further reading

Pillar

Part of Encoding & Crypto — Base64, URL, JWT, hashes, UUID, QR, password.


Written and maintained by Mian Ali Khalid. Last updated 2026-04-25.