🔒 Runs in your browser · nothing sent to a server

URL Encoder & Decoder

Encode and decode URLs the right way. Toggle between encodeURIComponent, encodeURI, and form-style + encoding — and see a per-character diff of exactly what changed. Fully client-side.

✔ 100% Free ✔ No signup ✔ Works offline ✔ Your text never leaves your browser
Mode:
Encodes every reserved character. Use this for query-string values and path segments — e.g. ?q=<value>.
Ready Enter text above and hit Encode or Decode.
Output
0 characters

Character diff

Run Encode to see which characters were percent-encoded.

Common encoded characters (encodeURIComponent)

Try an example:

What this tool does

Takes any text — a URL, a query-string value, a search string, an email, a path with spaces — and either percent-encodes it for safe transport in a URL, or decodes an already-encoded string back to plain text. All three JavaScript encoding modes are supported so you can pick the one that matches your context, and a per-character diff shows you exactly which bytes changed and why.

The three encoding modes

Why the diff view?

Percent-encoding bugs are notoriously hard to spot because a "wrong" URL often looks fine at a glance. The diff shows every character that got encoded, its output bytes, and its Unicode code point — so you can immediately answer questions like "did the + get encoded or not?", "is this really a space or a non-breaking space?", and "why is one URL 8 bytes longer than another?"

What it explicitly does NOT do

Percent-encoding reference

Percent-encoding replaces each byte that's reserved, unsafe, or non-ASCII with a % followed by two uppercase hex digits. For characters outside the ASCII range, the character is first encoded as UTF-8 and each of those bytes is percent-encoded individually. So é (U+00E9) becomes %C3%A9, and the pile-of-poo emoji 💩 (U+1F4A9, four UTF-8 bytes) becomes %F0%9F%92%A9.

The unreserved character set that never needs encoding is: A-Z a-z 0-9 - _ . ~. Everything else gets encoded by encodeURIComponent; encodeURI additionally preserves the reserved delimiters listed above so that a URL remains parseable after encoding.

Common percent-encoding mistakes

For the canonical rules, the RFC 3986 URI generic syntax and the current WHATWG URL Standard are the definitive references.

Working on APIs, integrations, or auth?

Browse backend, platform, and developer-tools engineering roles across 100+ companies profiled with real culture data.

Browse Engineering Jobs → Portfolio project ideas →

Frequently asked

What is the difference between encodeURIComponent and encodeURI?+
encodeURIComponent encodes every reserved URI character (including /, :, ?, #, &, =, +) because it assumes the input is a single query-string value or path segment that will be embedded inside a URL. encodeURI is meant for a full URL and deliberately preserves reserved characters that have structural meaning (/, :, ?, #, &, =, +, ,, ;, @) so the URL remains parseable. Rule of thumb: use encodeURIComponent for values you put into query strings and path segments; use encodeURI only when you have an already-formed URL that just needs its illegal characters escaped.
What is the difference between + and %20 for encoding spaces?+
Both represent a space, but in different contexts. %20 is the standard percent-encoding of a space and is valid anywhere in a URL. + only means space inside the query string of an application/x-www-form-urlencoded body or query, which is what HTML forms produce by default. Using + in a URL path is wrong — it will not be decoded to a space. If you're not sure, use %20; it is always safe. Pick the form-style mode in this tool when you specifically need HTML-form-compatible encoding.
Is it safe to paste a sensitive URL into this tool?+
Yes. All encoding and decoding happens entirely in your browser using the built-in JavaScript encodeURIComponent, encodeURI, and decodeURIComponent functions. The tool makes no network requests with your input, does not log it, and does not store it anywhere. You can verify by opening the browser DevTools Network tab while you use the tool — you will see no outbound requests carrying your text. That said, URLs frequently contain secrets (tokens, session IDs); if a URL is sensitive, treat any tool you paste it into with appropriate care and rotate the secret afterwards if in doubt.
Why am I getting a "Malformed encoded input" error when decoding?+
decodeURIComponent throws a URIError when it encounters a % sign that is not followed by two valid hex digits, or when the resulting bytes are not valid UTF-8. The most common causes are: (1) a raw % that was meant to be literal but was never encoded (should be %25), (2) truncated input where the last percent-escape is cut off (e.g. %E4%B8 missing its third byte), (3) mixed encoding where part of the string is double-encoded and part is not, and (4) input that was encoded as a different charset (Latin-1, Shift-JIS). Look for stray % characters, and if you know the input was double-encoded, decode twice.
When should I double-encode a URL?+
You double-encode when a URL will be embedded as a query-string value inside another URL. For example, a redirect_uri that itself contains query parameters must be encoded once so its & and = do not merge with the outer query string. If you naively encode https://example.com/callback?state=xyz once, an intermediate proxy or your own server-side URL parser might unpack it prematurely. Double-encoding — encoding the whole encoded string a second time — ensures the intended layer sees the correctly-encoded value. Most of the time you do NOT want double encoding; if you're passing a value between systems, encode exactly once at each boundary.
What is percent-encoding?+
Percent-encoding (also called URL encoding) is the mechanism defined by RFC 3986 for representing characters in a URL that are either reserved (used as delimiters like ? and #), unsafe (would confuse older systems, like space and quote), or non-ASCII. Each byte is replaced with a % followed by two uppercase hex digits, for example space becomes %20 and é (which is two UTF-8 bytes: 0xC3 0xA9) becomes %C3%A9. Modern browsers and JavaScript's built-in functions always use UTF-8 for multi-byte characters, which matches the current WHATWG URL Standard.