Skip to content
Control Plane Labs

URL Encoder/Decoder

Percent-encode and decode URLs with the right rules: component, full-URI, or form encoding, plus a query string parser and builder.

Privacy: Everything runs in your browser using the built-in URL APIs. Your input is never uploaded or logged.

Component mode escapes everything outside the unreserved set A–Z a–z 0–9 - . _ ~ plus the legacy marks !'()*. Tick the box to escape those too for strict RFC 3986 output.

All encoding happens in this tab. The shareable link carries inputs under 2 KB.

What it does

Percent-encodes and decodes URL text with the three encoding rules that actually differ in practice: component encoding for a single value, full-URI encoding for an assembled URL, and application/x-www-form-urlencoded for query strings and form bodies. Switch direction to decode, and malformed input gets an explanation rather than a thrown exception.

The second view takes a whole URL, splits the query string into decoded name/value pairs you can edit in place, and rebuilds a valid URL from whatever you leave behind. Repeated keys are preserved in order instead of being collapsed, which matters for APIs that accept ?tag=a&tag=b.

How it works

Encoding uses the platform’s own functions: encodeURIComponent, encodeURI, and URLSearchParams for the form variant. Parsing and rebuilding use URL and URLSearchParams, which implement the WHATWG URL Standard. Nothing is sent anywhere; your input round-trips through the query string of this page, up to 2 KB, so a link is shareable.

Which rule applies where

RFC 3986 splits URL characters into two groups. The unreserved set, A-Z a-z 0-9 - . _ ~, may appear literally anywhere. The reserved set, : / ? # [ ] @ ! $ & ' ( ) * + , ; =, carries structural meaning: those characters delimit the parts of a URL. Any other byte has to be percent-encoded as % plus two hex digits of its UTF-8 representation.

That distinction is the whole reason there are two encode functions. encodeURIComponent escapes everything outside the unreserved set, so it is safe for one query value or one path segment. encodeURI deliberately preserves the reserved delimiters so it can be run over an already-assembled URL without destroying it. Run encodeURI on a query value and an & inside that value stays literal, silently splitting one parameter into two. That single mistake is behind a large share of “the API says my parameter is missing” tickets.

Form encoding is the third case, and it is not RFC 3986 at all. The application/x-www-form-urlencoded serialiser is defined by the HTML Standard and encodes a space as +. That is correct in a query string and in a POST body and wrong everywhere else: in a path segment, + is a literal plus sign, so /files/my+file.txt and /files/my%20file.txt name different resources. When a downstream service reports a filename with a stray + in it, this is usually why.

One more sharp edge. encodeURIComponent implements the older RFC 2396 character classes, which treated !, ', (, ), and * as “mark” characters and left them alone. RFC 3986 reclassified them as sub-delimiters. Most servers do not care, but request-signing schemes that hash the encoded string, such as OAuth 1.0 and AWS SigV4, do. Tick the extra-escaping checkbox to percent-encode !'()* as well and get strict RFC 3986 output.

When to reach for it

  • A query parameter is arriving truncated or split and you need to see what the encoded form really looks like.
  • You are building a curl command by hand and a value contains spaces, ampersands, or non-ASCII characters.
  • A log line or redirect chain contains %2520 and you need to confirm it was double-encoded before you go blame a proxy.
  • You want to strip tracking parameters out of a link without hand-editing the string and getting the escaping wrong.

Also nearby: the curl command builder once the URL is correct, and the HTTP status reference for whatever the server said about it.

Frequently asked questions

encodeURI or encodeURIComponent — which one do I want?+
encodeURIComponent for a single piece of a URL: one query value, one path segment, a cookie value. encodeURI for a whole URL you have already assembled, because it deliberately leaves the reserved delimiters : / ? # [ ] @ ! $ & ' ( ) * + , ; = intact. Using encodeURI on a query value is the classic bug: an & inside the value stays literal and splits your parameter in two.
Why did my space become a + instead of %20?+
That is application/x-www-form-urlencoded, the legacy form-submission serialisation that the WHATWG URL spec still defines for query strings. + means space only in a query string or a form body. In a path segment a + is a literal plus, which is why /files/my+file.txt and /files/my%20file.txt are different resources.
Why does encodeURIComponent leave !'()* unescaped?+
It implements the older RFC 2396 character classes, where those were "mark" characters. RFC 3986 moved them into the reserved sub-delimiter set. Most servers do not care, but OAuth 1.0 signatures, S3 request signing, and some strict parsers do. Tick Also escape !'()* when you need output that matches RFC 3986 exactly.
Can I double-decode a value that looks like %2520?+
Yes, run Decode twice. %2520 is %20 that was encoded again, usually by a proxy or a client library that escaped an already-escaped string. If decoding once leaves you with visible % sequences, that is the tell. Fix the producer rather than decoding twice in production code.
What does the query string view do that the browser address bar does not?+
It splits a URL into decoded name/value pairs you can edit as plain text, keeps repeated keys in order instead of collapsing them, and re-serialises with URLSearchParams so the result is always valid. Handy for stripping tracking parameters or for building a request by hand without hand-escaping every value.