🔗 URL Encoder / Decoder

Percent-encode text for URLs or decode encoded URLs back to plain text. Runs entirely in your browser.

MODE

Component encoding (encodeURIComponent) escapes everything except unreserved characters — including & = / ? : @ + # . Use it for a single query-parameter value or path segment.

PLAIN TEXT0 chars
ENCODED URL
Output will appear here

About the URL Encoder / Decoder

URLs may only contain a limited set of characters. Anything else — spaces, accented letters, symbols like &, ?, /, or # when they aren't acting as delimiters — must be percent-encoded: replaced with a % followed by the character's hexadecimal byte value (a space becomes %20). This tool encodes text into that form and decodes it back, entirely in your browser.

It offers the two encoding modes JavaScript itself distinguishes: encodeURIComponent for single values, and encodeURI for whole URLs. The auto-detect hint notices when your input already looks encoded and offers to switch direction.

How to use it

  1. Choose Encode or Decode, then paste your text or URL.
  2. Pick a mode — Component for a single query value or path segment, Full URL for an entire address.
  3. Watch the auto-detect hint: if your input already looks encoded (or already looks plain), it offers to switch direction with one click — but you stay in control.
  4. Review the highlighted changes to see exactly which characters were percent-encoded, then copy the output.

Component vs. Full URL

Component encoding (encodeURIComponent) escapes reserved characters like & = / ? : @ #, because inside a single parameter value those characters would otherwise break the URL structure. Full-URL encoding (encodeURI) deliberately leaves those delimiters intact so a complete URL keeps working, and only escapes truly unsafe characters such as spaces. Rule of thumb: encoding one value → Component; encoding a whole address → Full URL.

Features

🔁 Two-way

Encode plain text to percent-encoding, or decode an encoded URL back to readable text.

💡 Auto-detect

Notices when input already looks encoded (or plain) and suggests the right direction — you can override.

🎛 Component vs full URL

Switch between encodeURIComponent and encodeURI, with a plain-language explanation of each.

🔎 Change highlight

Every percent-encoded sequence is highlighted so you can see exactly what changed.

🚦 Safe on bad input

Malformed percent-encoding shows a clear inline message instead of a raw error.

🔒 100% client-side

All encoding and decoding happen in your browser. Nothing is sent to a server.

Frequently Asked Questions

What's the difference between encodeURI and encodeURIComponent?

encodeURIComponent escapes almost every reserved character, so it's meant for a single piece of a URL — one query-parameter value or path segment. encodeURI leaves URL delimiters like : / ? & = # intact so an entire URL still functions, escaping only unsafe characters like spaces. Use Component for values, Full URL for whole addresses.

Why does a space sometimes become %20 and sometimes +?

Percent-encoding turns a space into %20. The plus sign (+) for a space is a separate convention specific to the application/x-www-form-urlencoded format used by HTML form submissions and query strings. This tool uses standard %20 percent-encoding; if you need form-style encoding, replace %20 with + in query strings.

My decode failed with an error — why?

Decoding fails when the input contains malformed percent-encoding, such as a lone % not followed by two hex digits, or an invalid sequence like %ZZ. The tool catches this and shows an inline message instead of crashing. Check for stray % characters in your input.

Does this handle non-English characters and emoji?

Yes. Characters are encoded as their UTF-8 bytes, so accented letters, non-Latin scripts, and emoji all round-trip correctly — encode then decode returns exactly what you started with.

Is my input private?

Completely. All processing uses the browser's built-in encoding functions locally. Nothing you enter is transmitted to or stored on any server.

URL encoding guide: percent-encoding, encodeURI vs encodeURIComponent

A URL may only contain a small set of characters. Everything else has to be percent-encoded: each byte becomes a % followed by two hex digits, so a space becomes %20 and an ampersand inside a value becomes %26. Getting this wrong rarely fails loudly. The request succeeds, the server simply reads a different value from the one you meant, and a parameter quietly ends at the first stray & or #.

RFC 3986 sorts characters into three groups. Unreserved characters — A-Z, a-z, 0-9, hyphen, period, underscore and tilde — never need encoding. Reserved characters are the delimiters: the gen-delims : / ? # [ ] @ and the sub-delims ! $ & ' ( ) * + , ; = . Those are the interesting ones, because they must stay literal when they are acting as structure and must be escaped when they are part of a value. Everything else becomes its UTF-8 bytes.

This tool exposes the two functions JavaScript itself distinguishes. Component mode is encodeURIComponent and decodeURIComponent, meant for one value at a time. Full URL mode is encodeURI and decodeURI, meant for a complete address. Picking the wrong one is the single most common cause of a mangled query string, and the two are not interchangeable in either direction — including when decoding.

Alongside the output the tool highlights every %XX sequence it produced or found, shows a live character count, and offers a Swap button that flips the direction and feeds the output back into the input box. That is the fastest way to prove a value survives a full encode-then-decode round trip unchanged. An auto-detect hint appears when the input already looks like it is in the other state, and offers to switch for you.

How it works

Component mode leaves 71 characters untouched: the 62 alphanumerics plus - _ . ! ~ * ' and the two parentheses. Everything else is escaped, including / ? : @ & = + $ # , ; and space. That set is slightly wider than RFC 3986's unreserved set — the five characters ! * ' ( ) are holdovers from the older RFC 2396 and count as sub-delims under the current specification. If a strict parser on the receiving end objects to them, replace them with %21 %2A %27 %28 %29 by hand.

Full URL mode leaves the URL delimiters alone — ; , / ? : @ & = + $ and # — so a complete address keeps working, and escapes only what would be unsafe, chiefly spaces and non-ASCII text. It is not a no-op on every structural character, though: encodeURI does escape square brackets, so a literal [ becomes %5B. That matters if you are hand-building a bracketed array parameter such as filter[status].

Decoding is asymmetric in a way that regularly catches people out. decodeURIComponent decodes every valid %XX sequence. decodeURI deliberately refuses to touch the escapes for reserved characters, so pasting %2F%23%26 into Full URL mode returns %2F%23%26 completely unchanged — it will not decode an escape that would alter the URL's structure. If a decode appears to do nothing at all, you are almost certainly in Full URL mode and want Component.

Non-ASCII text is encoded as UTF-8 bytes, one %XX per byte, so the expansion depends on the character: e-acute is %C3%A9 at two bytes, the rupee sign is %E2%82%B9 and Devanagari ka is %E0%A4%95 at three, and a grinning-face emoji is %F0%9F%98%80 at four. Decoding validates those sequences, which is why a truncated pair such as %E0%A4 raises a URIError. The tool catches it and shows an inline message instead of clearing the output with no explanation.

Common uses

  • Build a query parameter whose value contains an &, =, ? or # without truncating the rest of the query string.
  • Decode a redirect_uri, state or continue parameter pulled out of an OAuth or SSO flow to see where it actually points.
  • Read a percent-encoded request path out of an access log, a CDN report or an APM trace.
  • Check what a search or filter URL is really sending before pasting it into a bug report.
  • Encode a file name containing spaces, brackets or non-Latin characters for use in a download link.
  • Diagnose a value that reached the server still showing %20, or worse %2520, by round-tripping it here with the Swap button.
  • Prepare a value for a curl command line, where an unencoded & would otherwise be read by the shell as a request to background the job.

Before you rely on the result

  • Encode values, not whole query strings. Running Component mode over name=a&city=b turns the & into %26 and the = into %3D, and the server then sees a single parameter with one long peculiar value. Encode each value on its own and join them with literal delimiters yourself.
  • This tool does not do form encoding. HTML form submissions and most browser-written query strings use application/x-www-form-urlencoded, in which a space is + rather than %20. decodeURIComponent does not undo that: decoding hello+world returns hello+world, not hello world. Convert + to a space before decoding form data.
  • Double-encoding announces itself as %25. Because % is itself encoded as %25, encoding twice turns a space into %2520 and an ampersand into %2526. If you see %25 followed by two more hex digits inside a value, some layer in the chain encoded an already-encoded string.
  • Do not run Component mode over the scheme, host and port. https://example.com becomes https%3A%2F%2Fexample.com, which is correct only when the entire URL is being carried as a value inside another URL — a redirect_uri, for instance — and wrong everywhere else.
  • A percent-encoded slash inside a path segment is not universally accepted. Apache httpd rejects %2F in the path with a 404 unless AllowEncodedSlashes is enabled, Tomcat rejects it unless explicitly configured to allow it, and Spring Security's default StrictHttpFirewall rejects requests containing encoded slashes, encoded periods or semicolons outright. If an identifier can contain a /, put it in the query string rather than the path.
  • International domain names are not percent-encoded. Hosts use Punycode instead, so encoding a URL whose host is in Devanagari or Chinese produces a host made of %E0%A4-style bytes that will not resolve. Convert the host to its xn-- form separately and percent-encode only the path and query.
  • The auto-detect hint is a pattern match, not proof. It looks for any %XX sequence, so text that legitimately contains one — a printf format string such as %2d, or documentation that quotes an encoded URL — can be flagged as already encoded. It only ever suggests a direction; it never switches modes on its own.
  • Never substitute the legacy escape() and unescape() functions. They are not UTF-8 aware, emitting the non-standard %uXXXX form for characters above U+00FF, and they are deprecated precisely because their output is not valid percent-encoding.