URL Encode / Decode

Percent-encode or decode URLs and query strings.

100% in your browser — nothing uploaded

Encode or decode a URL online

Example loaded — edit it or clear it

About this URL encoder and decoder

URLs can only carry a limited set of characters, so spaces, accents, ampersands and most symbols have to be percent-encoded: a space becomes %20 and ñ becomes %C3%B1. Paste your text, press Encode or Decode, and the result appears below. The conversion runs entirely in your browser, so a query string containing tokens or customer data never leaves your device.

There are two modes. Component mode uses encodeURIComponent and escapes everything that is not a letter, a digit, or one of - _ . ! ~ * ' ( ) — including /, ?, & and =. Use it for a single value going into a query string. Full-URL mode uses encodeURI, which leaves the structural characters intact so the address still works as an address. Component mode is what you want most of the time; full-URL mode is for cleaning up a whole URL someone pasted with spaces or accents inside it.

Percent-encoding operates on bytes, not characters. Each byte becomes a % followed by two hexadecimal digits, so anything outside ASCII expands: é is one character but two UTF-8 bytes (C3 A9), which is why it encodes to %C3%A9 rather than a single triplet. RFC 3986 treats %c3%a9 and %C3%A9 as the same value and recommends uppercase hex when normalizing. It also defines a set of unreserved characters — A–Z, a–z, 0–9, hyphen, period, underscore and tilde — that never need encoding; encoding them anyway yields a URI that is technically equivalent but longer and harder to read.

Two mistakes account for most of the trouble. The first is double encoding: run the same string through an encoder twice and every % becomes %25, so caf%C3%A9 turns into caf%25C3%25A9. If you see %25 in a URL, something encoded an already-encoded string, and one decode pass will only get you halfway back. The second is the plus sign. In form-encoded query strings a + means a space, but decodeURIComponent does not know that and returns a literal +. This tool takes the pragmatic route and converts every + to a space before decoding — correct for form data, wrong if your value legitimately contains a plus, such as a base64 payload or a phone number in +1 format. In that case the + should have been encoded as %2B before it ever reached the URL.

Do not use this as a substitute for building URLs properly. If you are assembling an address in code, the URL and URLSearchParams objects handle escaping, parameter joining and the + convention for you, and are far harder to get wrong than string concatenation. Percent-encoding is also not HTML escaping — for < and & inside markup you want HTML entities. And it does not apply to the domain: an internationalized hostname like piñata.mx becomes Punycode (xn--piata-pta.mx), not percent-encoded. One last limit: encodeURIComponent throws a URIError on a lone surrogate, the unpaired half of an emoji, so text copied from a broken source can refuse to encode at all.

RFC 3986 reserved characters and their percent-encoded forms

RFC 3986 sorts ASCII into three groups. Unreserved characters — A–Z, a–z, 0–9 and - . _ ~ — are always safe. Reserved characters are the delimiters that give a URL its structure; encode one only when it is data rather than punctuation. Everything else has no legal place in a URL and must always be encoded. The reserved set splits into gen-delims, which separate the major parts of a URL, and sub-delims, used inside those parts.

CharacterEncodedWhat it delimits
:%3AEnds the scheme (https:) and separates a host from its port
/%2FSeparates path segments; a leading // opens the authority
?%3FStarts the query string
#%23Starts the fragment — nothing after it is sent to the server
[%5BOpens an IPv6 literal host, as in http://[::1]/
]%5DCloses an IPv6 literal host
@%40Separates userinfo from the host, as in user@example.com

The sub-delims have no fixed meaning in the URI grammar — each scheme decides — but the query-string conventions below are near-universal in practice.

CharacterEncodedConventional meaning
&%26Separates one query parameter from the next
=%3DSeparates a parameter name from its value
+%2BA literal plus — but reads as a space in form-encoded queries
;%3BLegacy separator for path (matrix) parameters and old cookie syntax
,%2CList separator inside a single path segment
$%24No assigned meaning; some APIs use it to mark system parameters
! ' ( ) *%21 %27 %28 %29 %2AReserved, yet encodeURIComponent leaves all five unescaped

Anything outside those two groups and the unreserved set must be encoded, including the ones people forget: space %20, the percent sign itself %25, and " %22, < %3C, > %3E, \ %5C, ^ %5E, ` %60, { %7B, | %7C, } %7D. Encoding % is not optional — it is the escape character, so leaving one raw makes the next two characters ambiguous.

The two JavaScript functions differ on exactly this reserved set. encodeURI leaves alone every unreserved character plus # $ & + , / : ; = ? @ and the five marks ! ’ ( ) *, which is why it can encode a whole URL without destroying it. encodeURIComponent leaves alone only the unreserved characters and those same five marks — so for strict RFC 3986 compliance you have to patch those five in yourself.

Input               https://ejemplo.com/búsqueda?q=café con leche&x=a+b#top

encodeURI           https://ejemplo.com/b%C3%BAsqueda?q=caf%C3%A9%20con%20leche&x=a+b#top
encodeURIComponent  https%3A%2F%2Fejemplo.com%2Fb%C3%BAsqueda%3Fq%3Dcaf%C3%A9%20con%20leche%26x%3Da%2Bb%23top
Full-URL mode keeps the address usable; component mode collapses it into one opaque value. encodeURI leaves the + in a+b alone, and does not encode the # either.

Why + and %20 both exist: %20 is the RFC 3986 answer, while + comes from application/x-www-form-urlencoded, the format HTML forms have used since the 1990s and which the WHATWG URL Standard still specifies — its serializer emits + for a space and %2B for a real plus. That is why URLSearchParams turns "café con leche" into caf%C3%A9+con+leche while encodeURIComponent gives caf%C3%A9%20con%20leche. Both round-trip fine on a server that knows which format it is reading; bugs start when it guesses wrong.

Reference tables

FAQ

When should I use component vs full-URL mode?

Use component mode for a single value going into a query string. Use full-URL mode when encoding an entire URL whose slashes and question marks must stay intact.

Why does my decoded text show weird characters?

The text was probably double-encoded. Decode it a second time.

Does + mean a space?

In query strings, historically yes. This tool decodes + as a space when decoding, and encodes spaces as %20.

Related tools