QuickUse Generator

URL Encoder/Decoder

Percent-encode or decode URLs and query strings in your browser. Component or URI variant, UTF-8 multi-byte safe. 100% client-side.

Mode
Variant

encodeURIComponent — encodes every reserved character. Use for query values, path segments, fragments.

0 / 10000 chars
Encoded output
The percent-encoded output appears here as you type.

Variant: Component (strict)

Editorial guide

About this generator

An honest technical read on what is happening behind the Generate button.

URLs are picky. They only speak ASCII, and even within ASCII they reserve a handful of characters for structural meaning — the slash between path segments, the question mark before the query, the ampersand between parameters. Anything else needs to be wrapped in percent encoding before it travels across the wire.

What URL encoding actually is

Percent encoding is defined in RFC 3986, the same document that defines URI syntax. The rule is small: take any byte you cannot spell directly in a URI, write it as % followed by two hexadecimal digits. A space becomes %20. An ampersand inside a query value becomes %26 so it does not get mistaken for a parameter separator. A multi-byte UTF-8 character likeç becomes two percent triplets — %C3%A7 — because UTF-8 spells that character in two bytes.

RFC 3986 §2.2 splits the special characters into two buckets. gen-delims (: / ? # [ ] @) are the major structural separators. sub-delims (! $ & ' ( ) * + , ; =) carry sub-component meaning, especially inside query strings. When data you want to pass through a URI would clash with any of these as delimiters, you encode it.

A short history — why the rules look like this

The earliest URL specification, RFC 1738 (Berners-Lee, Masinter, McCahill, 1994), already carried percent encoding. The 1994 design was small and ad-hoc: a fixed list of "unsafe" characters, an "ASCII-or-percent" rule, no Unicode story because UTF-8 was still settling. RFC 1866 (1995), the original HTML 2.0 spec, added the + for space convention because typing %20 in a form post was awkward in the dial-up era.

RFC 3986 (2005) merged these and added the formal split between unreserved characters (always safe), gen-delims (structural separators), and sub-delims (sub-component separators, mostly inside query strings). The WHATWG URL Living Standard refines the model further, defining named percent-encode sets — five of them, including the component set used by encodeURIComponent and the form-encoded set used by HTML form serialisation. The takeaway: when an old API and a new API disagree on whether something should be encoded, the old one is usually RFC 1738 vintage and the new one is WHATWG. Both can be right depending on the channel.

encodeURIComponent vs encodeURI — pick the right knife

Both functions are part of every browser and every Node runtime. They differ in how much of the reserved set they touch. encodeURIComponent is strict: it escapes everything except letters, digits, and the four unreserved marks - _ . ~ (plus the historical ! * ' ( )). Use it for query values, path segments, fragment identifiers — anywhere you are dropping a string into a slot of a URI you already control.

encodeURI is more forgiving: it preserves the URI's own structural characters (/, ?, :, @, &, =, +, $, #, ,, ;) on the assumption that you are handing it a full URL and just want spaces and accents normalised. If you reach for encodeURI when you wanted encodeURIComponent, an ampersand inside a value will silently turn into a parameter separator. That class of bug is hard to catch by eye and easy to ship to production.

The + versus %20 trap

One percent-encoding question keeps coming back: should a space be %20 or +? Both are correct, in different contexts.

%20 is the RFC 3986 answer. It applies everywhere in a URI — path, query, fragment. + is the application/x-www-form-urlencoded answer. That format was first standardised in RFC 1866 as the default HTML form encoding, and the convention that a space becomes + stuck. The WHATWG URL Living Standard preserves both rules side by side: its component percent-encode set emits %20; its application/x-www-form-urlencoded percent-encode set emits + and escapes the literal + in the input.

This generator emits %20 in both variants, because encodeURIComponent and encodeURI follow RFC 3986. If you need form-style encoding, you can post-process the output by replacing %20 with + — but only when you know the consumer expects form encoding. Mixing the two on a decoder side is where most "my space turned into a plus" bugs live.

Decoding is the forgiving end of the round trip

decodeURIComponent is a superset. It accepts the output of both encodeURIComponent and encodeURI and produces the original string. There is no need to know which variant the encoder used. That is why Decode mode here has no variant toggle — one decoder covers both.

The only thing that breaks decoding is malformed percent encoding. A bare %, a %G1 sequence, an incomplete trailing %2 — any of these will raise a URIError from the underlying runtime. The widget catches that and surfaces a friendly message. The common cause is input that was copy-pasted through something that mangled the alphabet — a chat client that ate the second hex digit, a form field that decoded too eagerly. When the decoder rejects an input, re-check the source before assuming the algorithm is broken.

Where this actually matters

  • Query parameters. Any time you build a search URL or a tracking link, user-supplied values go through encodeURIComponent. An unencoded & or = in a value silently truncates the parameter on the server side.
  • Path segments with user content. Routes like /users/{username} need encoding when the username can contain spaces, slashes, or accents. Same applies to OAuth state, signed URLs, anything where the path carries data.
  • Fragments. Single-page apps that route via the hash (# section) still need encoding for non-ASCII content.
  • Multi-byte content. Asian languages, emoji, accented Latin — they all go through UTF-8 first, then percent-encode the bytes. The generator does this natively; you do not need a separate UTF-8 pre-pass.

What URL encoding is not

It is not encryption. The output is fully reversible by anyone who reads it. Putting a password or a session token into encodeURIComponent hides nothing — the intermediate proxies and the access logs see the decoded value the moment the receiver decodes it. If you need confidentiality, use TLS for transport and a real cipher for storage.

It is not Base64 either. Base64 packs arbitrary binary into a small ASCII alphabet of 64 characters; URL encoding escapes individual reserved characters from any string. If you want to put binary data into a URL safely, the right combination is Base64URL (RFC 4648 §5) followed by URL encoding only if needed — Base64URL was designed to slot into a URL without further escaping.

Privacy and client-side encoding

Every percent-encoding step in this tool runs in the browser. Nothing leaves the page. That matters more than people think for query data — the moment you paste a URL into a server-side encoder, the server has seen your tokens, your CPF, your private parameter values. A 100% client-side tool removes that surface entirely. The recent-inputs panel stores only your inputs (mode + variant + timestamp), never the encoded output, in your browser's localStorage. Clearing the panel is one click.

Frequently asked questions

Is URL encoding a form of encryption?

No. URL encoding (percent encoding) is fully reversible by anyone who reads the output. It exists to transport bytes that have structural meaning inside a URI — reserved characters, spaces, accents, non-ASCII — through a system that only understands ASCII. If you need confidentiality, use TLS for transport and a real cipher (AES, ChaCha20). "I URL-encoded the password" is a common production bug, not a security control.

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

%20 is the RFC 3986 percent encoding for ASCII 0x20 (space). It works everywhere in a URI. The + is the application/x-www-form-urlencoded convention — historically introduced by RFC 1866 for HTML form submissions and preserved by the WHATWG URL Standard. Form-encoders emit + for space; URI-encoders (encodeURIComponent, encodeURI) emit %20. This tool follows RFC 3986, so it emits %20. If your consumer expects form encoding, post-process by replacing %20 with +.

What is the difference between encodeURIComponent and encodeURI?

encodeURIComponent is strict — it encodes everything except letters, digits, and the unreserved characters (- _ . ~ ! * ' ( )). Use it for query values, path segments, and fragments where you want a string to slot safely into a URI you control. encodeURI is permissive — it preserves the URI structural characters (/, ?, :, @, &, =, +, $, #, ,, ;) on the assumption that the input is already a full URL and you only want spaces and accents normalised. Pick the wrong one and an unescaped & inside a value can silently corrupt your query string.

Can I encode Cyrillic, CJK, or emoji?

Yes — both encodeURIComponent and encodeURI handle arbitrary Unicode natively. The character is first converted to its UTF-8 byte representation, then each byte is percent-encoded. 日本語 becomes %E6%97%A5%E6%9C%AC%E8%AA%9E (three 3-byte UTF-8 characters → nine percent triplets). Emoji like 🎉 (4-byte UTF-8) become four percent triplets. Decoding reverses the process via decodeURIComponent. No separate UTF-8 pre-pass needed.

Why does my JavaScript decoder throw on input that looks fine?

decodeURIComponent throws URIError on malformed percent sequences — a bare %, a %G1 (invalid hex), an incomplete %2 at the end of the string, or a sequence that decodes to invalid UTF-8 bytes. The common culprits are inputs that went through a system that mangled them: a chat client that ate a character, a form field that decoded once already, or a copy-paste through a context that normalised characters. Check the source before assuming the algorithm is broken.

Does this tool send my input anywhere?

No. Encoding and decoding happen entirely in your browser via the standard JavaScript URI functions. There is no fetch, no XHR, no analytics call that captures your text. The recent-inputs panel stores only your inputs (mode + variant + timestamp) in your browser's localStorage — never the encoded output. Clearing the panel is one click.

How does URL encoding interact with Base64?

They solve different problems and often combine. Base64 packs arbitrary binary into a 64-character ASCII alphabet so it can travel through text channels. URL encoding escapes reserved URI characters from any string. Plain Base64 contains + and /, which are reserved inside URIs, so passing Base64 through a URL needs an extra URL-encode pass. Base64URL (RFC 4648 §5) was designed to dodge this: it uses - and _ instead of + and / so the output is URL-safe with no further escaping. If you have binary data heading into a URL, prefer Base64URL.

Why does my CPF or e-mail address need encoding in a query string?

CPF itself is digits and a dash; it does not strictly need encoding, but it costs nothing to pass it through encodeURIComponent and you cover edge cases where someone formats it with dots. E-mail addresses are trickier — the @ is a reserved character (RFC 3986 §2.2 gen-delim), and the + that some people use for sub-addressing collides with the form-encoding convention. Always run user-supplied values like e-mails through encodeURIComponent before slotting them into a query parameter.