HTML Formatterhtmlformatteronline.com

URL encoder and decoder

Percent-encode a value for a query string, or decode one you have been handed. One tick box switches between encoding a single component and a whole address.

Input 0 lines
Encode
Encoded 0 lines
Paste text on the left and press Encode, or switch to Decode.

Two different jobs, one tick box

Percent-encoding replaces characters that mean something structural in a URL with a % and their byte value. Which characters need replacing depends entirely on whether you are encoding a whole URL or a single value inside one. Getting this backwards is the most common URL bug there is.

Component (default)Whole URL (ticked)
Use forOne parameter value, one path segmentA complete address
Encodes / ? : @ & = + $ #YesNo
Encodes spaces and non-ASCIIYesYes
JavaScript equivalentencodeURIComponentencodeURI

Leave the box unticked when you are encoding something that goes into a URL — a search term, a redirect target, a filename. Tick it when you have an entire address containing spaces or accented characters and you want the structure left intact.

Why it matters, with an example

You are building a redirect link and the destination is itself a URL with parameters.

Wrong — the destination's parameters escape
https://acme.test/go?to=https://other.test/p?id=9&ref=mail

The server reads three parameters on your URL: to, id and ref. The destination has been torn apart.

Right — the destination is one encoded value
https://acme.test/go?to=https%3A%2F%2Fother.test%2Fp%3Fid%3D9%26ref%3Dmail

Now there is one parameter whose value happens to be a URL, and it survives intact. This is the case that breaks analytics links, OAuth callbacks and email tracking every day.

Plus signs and spaces

A space can appear in a URL two ways. As %20, which is correct anywhere. Or as +, which means a space only inside a query string, and only because HTML form submission (application/x-www-form-urlencoded) defined it that way in the 1990s.

In a path, + is a literal plus sign. So /files/report+final.pdf is a file with a plus in its name, while ?q=report+final is a search for "report final".

Tick Read + as a space when decoding a form submission or a query string. Leave it off when decoding a path, or you will corrupt any genuine plus signs — which matters most with email addresses using the user+tag@example.com convention.

Reserved and unreserved characters

RFC 3986 splits URL characters into two groups. Unreserved characters — A–Z a–z 0–9 - . _ ~ — are never encoded and never need to be. Everything else is either reserved, meaning it has a structural job, or outside the allowed set entirely.

CharacterEncodedStructural meaning
space%20Not allowed in a URL at all
&%26Separates query parameters
=%3DSeparates a parameter from its value
?%3FStarts the query string
#%23Starts the fragment — never sent to the server
/%2FSeparates path segments
+%2BMeans a space in a query string
%%25Starts an escape sequence

Non-ASCII characters are encoded as their UTF-8 bytes, so é becomes %C3%A9 — two bytes, two escapes. That is why an encoded Japanese or Arabic URL looks so much longer than the original.

Doing it in code

JavaScript
encodeURIComponent("linen shirt & scarf")   // linen%20shirt%20%26%20scarf
encodeURI("https://a.test/my file.pdf")     // https://a.test/my%20file.pdf

// building a query string properly
const qs = new URLSearchParams({{ q: "linen shirt", sort: "price asc" }});
`/search?${{qs}}`                             // /search?q=linen+shirt&sort=price+asc
Python
from urllib.parse import quote, quote_plus, urlencode
quote("linen shirt")         # linen%20shirt
quote_plus("linen shirt")    # linen+shirt
urlencode({{"q": "linen shirt", "sort": "price asc"}})

In both languages, building the query string with the provided helper rather than by concatenating strings removes this whole category of bug. Use URLSearchParams or urlencode and you will never have to think about it again.

Questions about this tool

Which mode should I use?

If you are encoding one value that will sit inside a URL — a search term, a redirect target, a filename — leave the box unticked. If you have a whole address that contains spaces or accented characters and you want :// and ? left alone, tick it.

Why does decoding sometimes fail?

Because a % is not followed by two valid hex digits. That usually means the text was double-encoded, or a genuine percent sign was never escaped. Try decoding twice — if the first pass produces something still full of %25, it was double-encoded.

What is double encoding and why is it a problem?

Encoding something that was already encoded. %20 becomes %2520, and the receiving end decodes it once and gets %20 as literal text rather than a space. It happens when a value passes through two layers that each helpfully encode it. Decode until the output stops changing to see how many layers deep you are.

Does the fragment after # get sent to the server?

No. Everything after # is handled by the browser and never leaves it. That is worth knowing when you are debugging why a server cannot see part of a URL.

Related tools

Learn the why, not just the how

Longer reading on formatting, indentation and minification.