URL Encoder / Decoder

Percent-encode and decode URLs, query strings and individual parameters right in your browser — with a character-by-character breakdown of exactly what got encoded and why.

Paste text, a parameter value or a full URL and the conversion runs live as you type. Pick the right flavour — component encoding (encodeURIComponent), whole-URL encoding (encodeURI) or form encoding (spaces become +) — and see every character mapped to its %XX form with a plain-English name. Decoding accepts percent-encoded text and query strings, reports invalid % sequences with their exact position, and splits query strings into a key/value table you can copy as JSON. The Query Builder assembles a correctly encoded query string from individual fields — handy when you are debugging an API call by hand.

🔒 100% private — nothing is uploaded or stored. Your URLs and query strings are converted entirely in your browser with plain JavaScript. They never touch our servers, are never written to disk, and the page keeps working even if your internet connection drops — which matters, because URLs often contain tokens, session IDs and other things you would rather not paste into a third-party web service.

Text → Percent-encoded

Not sure? Parameter values and search terms use “Text / parameter value”.
Type or paste text above — conversion runs as you type.

What got encoded?

Every character in your input, and what it became. Blue rows changed; grey rows were already URL-safe and passed through untouched.

Nothing to show yet.

What is percent-encoding?

A URL may only contain a small set of characters — letters, digits and a handful of symbols. Everything else is written as %XX, where XX is the hexadecimal value of one byte. To encode text, the browser first converts it to UTF-8 bytes, then rewrites each byte that is not allowed. A space (byte 20) becomes %20; the é in “café” is two UTF-8 bytes (C3 A9) and becomes %C3%A9. Decoding works the other way: every %XX becomes a byte, the bytes are read as UTF-8, and you have your text back.

The anatomy of a URL

Percent-encoding is applied per part — each part of a URL has its own rules about which characters are structural (must stay) and which are data (must be encoded):

PartExampleStructural charactersNotes
Schemehttps—Letters, digits, +, -, .
Hosttechgeek.biz—Reserved for the address; @ inside it would be ambiguous
Port:8443:Digits only after the colon
Path/search/results/Slashes separate segments; ? and # end the path
Query?q=url%20encoding?, &, =& separates fields, = joins key and value — so both must be encoded inside values
Fragment#results#Never sent to the server; a # in a value silently truncates the URL

This is why encoding the whole URL and encoding a parameter value are different operations: in a full URL the :/?&=# characters must survive, while inside a parameter value they are data and must become %3A, %2F, %3F, %26, %3D, %23.

Which encoder should I use?

FunctionEncodesUse it for
encodeURI(url)Everything except A–Z a–z 0–9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( )A complete URL you are embedding in an href, a redirect target, or a referrer
encodeURIComponent(value)Everything except A–Z a–z 0–9 - _ . ! ~ * ' ( ) — note :, /, ?, &, =, # are all encodedOne path segment or one query parameter value — the most common case
Form encoding (this tool’s “Form field” mode)Same as encodeURIComponent plus: spaces become + instead of %20, and !'()* are encodedHTML form submissions and application/x-www-form-urlencoded API bodies — what fetch(url, {body: new URLSearchParams(...)}) produces

Why does + mean space?

In application/x-www-form-urlencoded (the format HTML forms submit in), a space is written as + because it is shorter than %20. That convention applies only to form data. In a percent-encoded path or in most API query strings, + is just a plus sign. This is why the Decode tab has a “Treat + as space” switch: it is on for form data, off for paths and raw query strings. And the flip side — a literal plus inside a form value must be written %2B.

Common pitfalls

  • Double encoding. If your output contains %25 (an encoded percent sign), something encoded an already-encoded string — %2520 decodes to the literal text %20, not a space. Decode once, not twice.
  • The silent #. A fragment marker in a value — https://site.com/search?q=what#is%20new — is read as “value what, fragment is new”. The server never sees anything after the #. Encode it as %23.
  • & and = inside values. They split the query into fields that were never there. Always encode parameter values, never just the whole query string.
  • Spaces. A raw space in a URL is simply illegal — some servers tolerate it, some reject it, and browsers encode it for you, which is why “it works in the browser” but fails in your script.
  • Unicode. Percent-encoding is a byte encoding, so the result depends on the character set. Modern URLs use UTF-8: “café” is caf%C3%A9, not caf%E9 (the Latin-1 form). Mixing the two is a classic source of “café” bugs.
  • Decoding the wrong thing. A query string like ?a=1&b=2 should be split on & first, then each value decoded. Decoding the whole string first can change structural characters if a value contained %26 — wait, that is exactly what you want to avoid: %26 must stay & until it is decoded as part of its value, never treated as a field separator.

Want to do this from the command line instead? Python’s urllib.parse.quote/unquote, PowerShell’s [System.Uri]::EscapeDataString and JavaScript’s encodeURIComponent all implement the same component-encoding rules.

Nothing on this page leaves your browser: there is no server round-trip when you type or paste, no analytics on your inputs, and no storage of any kind.


Luke Keam
Thank you for reading. Email me: [email protected]
Luke Keam | techgeek.biz