Home › URL Encoder & Decoder

URL Encoder & Decoder

Developer toolRuns in your browserNothing uploaded

Encode or decode a URL

Why URLs need encoding

URLs may only contain a limited set of ASCII characters. Anything outside that set — spaces, accented letters, most symbols, any non-Latin script — must be percent-encoded: replaced by % followed by the byte's hexadecimal value.

A space becomes %20. An ampersand becomes %26. The letter é, which is two bytes in UTF-8, becomes %C3%A9.

Without this, a value containing & or = would be misread as a parameter separator, silently corrupting the request.

encodeURI versus encodeURIComponent

This is the distinction that causes most URL bugs, and it is worth getting right.

encodeURIComponent encodes almost everything, including & = ? / : #. Use it for individual values going into a query string or path segment. This is what you want the vast majority of the time.

encodeURI leaves the URL's structural characters intact, because it is designed to encode a complete URL without breaking it. Use it only when you have a whole URL containing illegal characters — typically spaces — that you need to make valid.

The classic bug: using encodeURI on a value that contains an ampersand. The ampersand survives unencoded, the server reads it as a parameter separator, and the value is silently truncated. Encoding a&b with encodeURIComponent gives a%26b, which arrives intact.

The plus-sign problem

There are two encoding conventions in circulation and they disagree about spaces.

Standard percent-encoding, per RFC 3986, encodes a space as %20. But HTML form submissions use application/x-www-form-urlencoded, which encodes a space as +.

The consequence is that a literal plus sign in form-encoded data must itself be encoded as %2B, or it will be decoded as a space. This is why phone numbers in international format frequently arrive with the leading plus missing — an encoding mismatch, not a data-entry error.

JavaScript's built-in functions use %20. If you are working with form-encoded data, URLSearchParams handles the plus convention correctly.

Reserved and unreserved characters

RFC 3986 divides characters into groups. Unreserved characters — A–Z a–z 0–9 - . _ ~ — never need encoding and should not be encoded.

Reserved characters — : / ? # [ ] @ ! $ & ' ( ) * + , ; = — have structural meaning. They must be encoded when they appear as data rather than as delimiters.

Everything else must always be encoded. Encoding an unreserved character is technically valid but produces a different string, which matters for cache keys, signatures, and any system that compares URLs literally.

Practical pitfalls

Double encoding. Encoding an already-encoded string turns %20 into %2520. This usually happens when a value passes through two layers that each encode. The fix is knowing which layer owns the encoding, not decoding first and re-encoding.

Encoding the whole URL. Running encodeURIComponent over a complete URL destroys it, encoding the :// and every slash. Encode the parts, then assemble.

Fragments. Everything after # is never sent to the server. Putting data there and expecting the backend to see it is a common misunderstanding.

Building URLs by hand. The URL and URLSearchParams APIs handle encoding correctly and are less error-prone than string concatenation.

Frequently asked questions

What is the difference between encodeURI and encodeURIComponent?

encodeURIComponent encodes almost everything including & = ? / and is used for individual values. encodeURI leaves structural characters intact and is used for a complete URL. Using the wrong one silently truncates values containing ampersands.

Why is a space sometimes %20 and sometimes +?

Standard percent-encoding uses %20. HTML form submissions use application/x-www-form-urlencoded, which uses +. This is why a literal plus must be encoded as %2B in form data.

What causes double encoding?

Encoding a string that was already encoded, turning %20 into %2520. It usually happens when a value passes through two layers that each apply encoding. The fix is deciding which layer owns it.

Which characters never need encoding?

The unreserved set: A-Z, a-z, 0-9, hyphen, period, underscore, and tilde. Everything else either has structural meaning or is outside the permitted ASCII range.