URL Encoder & Decoder

Percent-encode text for a URL or decode it back, with every broken escape pointed out by position. Paste a full link to see its parts, from the real host to each query parameter, decoded.

What do you want to do?

For one query value or path segment. Encodes / ? & = # and everything else that has a meaning in a URL.

Runs entirely in your browser. Nothing you type or upload is sent to a server.

Why URLs need encoding

A URL can only contain a small set of ASCII characters, and some of those have jobs. The ? starts the query, & separates parameters, = splits a name from its value and # starts the fragment. A value that contains one of them has to be disguised, or it changes the structure of the URL. Search for fish & chips and put it into a query string unencoded, and the server receives a search for fish plus a meaningless parameter called chips.

Percent-encoding is the disguise. Each byte that cannot appear as itself is written as % followed by its value in hexadecimal. Text that is not plain ASCII is first converted to UTF-8, so é, which is two bytes, becomes %C3%A9, and an emoji, which is four, becomes something like %F0%9F%98%80. The escapes you will see most often:

EscapeCharacterEscapeCharacter
%20space%26&
%2F/%3D=
%3F?%23#
%3A:%2B+
%40@%25% itself

Which kind of encoding to use

The four modes above differ only in which characters they leave alone, and picking the wrong one is the most common URL bug there is.

  • Encode a value matches JavaScript's encodeURIComponent. It leaves letters, digits and - _ . ! ~ * ' ( ) alone and encodes everything else. Use it for anything you are placing inside a URL: one query value, one path segment, or a whole URL being passed as a parameter to another URL.
  • Strict RFC 3986 also encodes ! ' ( ) *. OAuth 1.0 signatures and AWS request signing require exactly this, and a single unencoded parenthesis makes the signature fail.
  • Encode a whole URL matches encodeURI. It keeps the characters that give a URL its shape, so it repairs spaces and accents in a link without breaking it. It never protects a value, because it leaves & and = as they are. This version also leaves existing escapes alone and turns an international domain name into punycode, two things the built-in gets wrong.
  • Form-encode is application/x-www-form-urlencoded, the format HTML forms submit and URLSearchParams produces. Spaces become + and only letters, digits and * - . _ survive.

The plus sign problem

In form data a + means a space, but in a path, and in any query that was not built by a form, it is just a plus sign. Decoders therefore disagree, and values that really contain a plus get damaged. A phone number such as +44 20 7946 0000 or an address like me+news@example.com arrives with a space where the plus was, because it was sent unencoded and decoded as form data. The fix is to encode the value properly, which writes the plus as %2B. When decoding here, untick "Treat + as a space" for paths and other non-form text.

Double encoding

When a value is encoded and then encoded again, each % becomes %25, so a space ends up as %2520 and visitors see a literal %20 on the page. It nearly always means two layers of code each decided to encode the same value, which is common with redirect and tracking links that pass through several services. Encode a value once, at the moment it is placed in the URL, and decode it once when it is read. The decoder counts the layers and can peel off the next one.

Reading a URL's parts

A full URL reads scheme://user:password@host:port/path?query#fragment, and the breakdown panel separates each part. A few of them are worth knowing about:

  • Anything before an @ is not the website. In https://www.paypal.com@login-check.example/ the real host is login-check.example. The first part is a user name, and the trick works because people read from the left.
  • International domain names travel as punycode, starting xn--. A name that mixes alphabets, such as a Cyrillic а among Latin letters, can be made to look exactly like a well-known domain. The breakdown flags it.
  • The fragment never reaches the server. Everything after # stays in the browser, which is why single-page apps and some login flows put data there.
  • Repeated parameters are handled differently by every server. For ?tag=a&tag=b, PHP keeps only the last value, Python's parse_qs and Node's qs library return a list, and URLSearchParams.get returns the first.

To check a link from a printed code before opening it, use the QR code scanner. For other encodings, the Base64 converter handles data URIs and URL-safe Base64, and the JSON formatter tidies the API responses that query strings usually ask for.

Frequently Asked Questions

What is URL encoding?
URL encoding, properly called percent-encoding, replaces a character that is not allowed in a URL, or that would change its meaning, with a % sign and two hexadecimal digits. A space becomes %20 and an ampersand becomes %26. Characters outside plain ASCII are first converted to their UTF-8 bytes, and each byte is encoded, so é becomes %C3%A9.
What is the difference between encodeURI and encodeURIComponent?
encodeURIComponent is for a single value, such as a search term going into a query string. It encodes / ? & = # and the other characters that structure a URL, so the value cannot break out of its slot. encodeURI is for a complete URL. It leaves those characters alone so the URL still works, and only encodes spaces, non-ASCII text and a few others. Using encodeURI on a value is a common bug, because an & inside it survives and starts a new parameter.
Should a space be encoded as %20 or +?
Both are correct in different places. In the query string of a URL submitted by an HTML form, + means a space, because that is how forms encode data. Everywhere else, including in a path, a space must be %20 and + is a literal plus sign. %20 is accepted in query strings too, so it is the safer choice when you are building a URL by hand.
Why does my URL contain %2520?
It has been encoded twice. A space was encoded to %20, then the % sign was encoded again to %25, giving %2520. It usually happens when a value that is already encoded is passed to a function that encodes it once more, often in redirect or tracking URLs that pass through several systems. Encode each value exactly once, at the moment it goes into the URL. The decoder spots this and offers to decode a second time.
Why does decoding fail with "URI malformed"?
JavaScript's decodeURIComponent throws that error for a % sign that is not followed by two hex digits, such as 100% or %G1, and for escapes that do not form valid UTF-8, such as %C3%28. This tool decodes everything it can and lists each broken sequence with its position. A literal percent sign has to be written %25.
Does URL encoding hide or protect data?
No. Percent-encoding is a reversible spelling, not encryption, and anyone can decode it instantly. It only keeps a value from being misread as part of the URL's structure. Passwords and tokens in a URL can end up in browser history, server logs and analytics, so sensitive data belongs in the body of a request or a header.
Is it safe to paste a URL with a token in it?
Encoding, decoding and the breakdown all run in your browser, and nothing you type is sent to a server. Even so, treat a live password-reset link or session token like a password, and paste one that has expired when you only need to read its structure.
What is the punycode version of a domain?
Domain names that contain letters outside plain ASCII, such as münchen.de, are converted to an ASCII form starting with xn-- before they are looked up in DNS. münchen.de becomes xn--mnchen-3ya.de. The breakdown shows both forms, and warns when a name mixes alphabets, which is how look-alike phishing domains are built.
The Internet Omni-Tool