URL Encoder & Decoder

Paste anything — the tool detects whether it needs encoding or decoding, does it live, and highlights exactly what changed. Component vs full-URI modes, form-style + handling, batch lines, and a one-click fix for double-encoded %2520 messes. All in your browser.

Percent-encoding in one line: characters that can't appear in a URL are written as % + their byte value in hex — space → %20  ·  & → %26  ·  é → %C3%A9 Decoding reverses it. It's notation, not encryption — anything encoded can be read back.
Changed parts are highlighted.

Encoding and decoding run in your browser — your URLs are never sent anywhere, and the page works offline once loaded.

[ Ad slot — replace with AdSense / Ezoic code ]

What percent-encoding actually is

URLs are only allowed to contain a limited set of ASCII characters, so anything outside that set — spaces, accents, emoji, and characters that have jobs inside a URL like ? and & — is written as % followed by the byte's value in hexadecimal. A space becomes %20, é becomes %C3%A9 (its two UTF-8 bytes), & becomes %26. That's the whole mechanism: it's a reversible escape notation, not a cipher. Decoding just maps every %xx back to its byte and reassembles the text.

encodeURI vs encodeURIComponent — the #1 confusion

The two JavaScript functions differ in one crucial way, and picking the wrong one is the most common URL-encoding bug there is. encodeURIComponent escapes everything that isn't an unreserved character — including /, ?, &, =, :. It's for encoding one value that's going to be inserted into a URL, like a search query or a redirect target. encodeURI leaves the URL's structural characters alone and only escapes characters that can't appear in a URL at all. It's for cleaning up a whole URL without breaking its structure.

The failure modes are symmetrical: run a whole URL through encodeURIComponent and its slashes become %2F, breaking the path; build a query string with encodeURI and a value containing & silently splits into two parameters. Rule of thumb: component mode for values, full-URI mode for whole URLs — and this tool defaults to component mode because encoding a value is the far more common task.

Reserved vs unreserved characters

GroupCharactersEncoded?
UnreservedA–Z a–z 0–9 - _ . ~Never — always safe as-is
Reserved (delimiters): / ? # [ ] @Kept by encodeURI; escaped by encodeURIComponent
Reserved (sub-delims)! $ & ' ( ) * + , ; =Mostly kept by encodeURI; & ' ( ) etc. escaped by encodeURIComponent except ! ' ( ) * which JS historically leaves alone
Everything elsespace " % < > { } | \ ^ ` and all non-ASCIIAlways encoded, by both

"Why is my URL full of %2520?" — double encoding

If you see %2520 where a space should be, the URL was encoded twice: %20 was itself treated as text, so its % became %25. It happens whenever two layers of a system both "helpfully" encode — a template engine plus a redirect, a spreadsheet export plus a form submit. This tool detects the %25xx signature automatically and offers a one-click fix that decodes until the text stops changing (with a sanity cap), which recovers the original in every ordinary case.

Doing it in code

JavaScript

encodeURIComponent('coffee & cream')  // 'coffee%20%26%20cream'
decodeURIComponent('coffee%20%26%20cream')  // 'coffee & cream'
encodeURI('https://x.io/a b?q=1')  // 'https://x.io/a%20b?q=1'

Python

from urllib.parse import quote, unquote, quote_plus
quote('coffee & cream')        # 'coffee%20%26%20cream'
quote_plus('coffee & cream')   # 'coffee+%26+cream'  (form style)
unquote('coffee%20%26%20cream')  # 'coffee & cream'

PHP

rawurlencode('coffee & cream');  // 'coffee%20%26%20cream'
urlencode('coffee & cream');     // 'coffee+%26+cream'  (form style, + for space)
rawurldecode('coffee%20cream');  // 'coffee cream'

Note the pattern across languages: there's always a "spaces become %20" function and a "spaces become +" form-style sibling. The + convention is valid only in the query string — which is exactly what the + toggle above controls.

What this tool can't do

Shortened links — bit.ly, t.co, tinyurl and friends — are not encodings. The short code is a key into that service's database, so expanding one requires asking their server where it points, which no offline tool can do. If you paste a shortened link here, decoding it will (correctly) change nothing. Likewise, if a string looks scrambled but contains no % signs, it's probably Base64 or something else entirely, not percent-encoding.

Frequently asked questions

Can this decrypt a URL?

There's nothing to decrypt — percent-encoding is an open, reversible notation, not encryption. If you searched "decrypt URL," what you almost certainly want is exactly what this tool does: decoding %xx sequences back into readable characters. Genuine encryption in a URL (a token, a signed parameter) can't be reversed by anyone without the key, tool or no tool.

Is my URL sent anywhere when I use this?

No. Everything runs as JavaScript in your tab — no server, no network request containing your text. You can load the page, go offline, and it keeps working. That matters here more than for most tools, because URLs routinely contain tokens and session IDs you shouldn't paste into random websites.

When should spaces be + instead of %20?

Only in query strings, and only because HTML form submission (application/x-www-form-urlencoded) historically used +. In a path, + is a literal plus sign. When in doubt, %20 is always correct; + is correct only after the ?.

Why did decoding produce garbled characters like é?

That's a UTF-8 byte sequence being interpreted as Latin-1 — usually a sign the text was encoded from one character set and decoded as another somewhere upstream. The percent-decoding here is correct UTF-8; the mangling happened before the text reached you.

[ Ad slot — replace with AdSense / Ezoic code ]

Related tools