URL

URL encoder and decoder

Both directions at once, with accents, ñ and emoji handled properly. Plus two things almost nobody offers: taking a URL apart and editing its parameters in a table, and building campaign links with their QR code.

Zero uploads · all in your browser

The URLs you paste never leave this page.

Why it matters that this is not uploaded

A URL looks like public data, and it almost never is. The ones people paste into a tool like this carry session identifiers, internal admin panel paths, customer references, single-use password-reset keys, or pages that have not been published yet. Any of those sitting in a stranger's server log is a problem, and for nothing in return: turning a space into %20 needs no server at all. Here there is nowhere to send it.

How it works, in 3 steps

  1. Paste into either side

    Type ordinary text on the left and it comes out encoded on the right, or paste something encoded on the right and it comes out readable on the left. It updates as you type.

  2. Pick what you are encoding

    A single value or a whole address. The example above shows the difference using the same phrase in both modes — which is exactly where everyone goes wrong.

  3. Or move to the other tabs

    Take a URL apart and edit its parameters, build a campaign link with its QR, or paste an enormous link and see in plain text what it carries.

What people use it for

The two modes, and why picking wrong breaks the link

This is what brings most people here, and it takes one line to explain: the difference is whether the characters that give the address its structure get encoded — the colon, the slashes, the question mark, the hash, the ampersand and the equals sign.

Starting from the same phrase, https://example.com/my page?q=café:

  • As a single value it becomes https%3A%2F%2Fexample.com%2Fmy%20page%3Fq%3Dcaf%C3%A9. It is no longer an address: it is a piece of text. And that is exactly what you need in order to put it inside another address's parameter, which is where all those url=https%3A%2F%2F… strings come from.
  • As a whole address it becomes https://example.com/my%20page?q=caf%C3%A9. It is still an address, with its slashes and question mark untouched, but with the space and the accent fixed. That is what you need to repair an address that already is one.

Getting it wrong fails in both directions. Encode a whole address as if it were a value and it becomes text that leads nowhere. Encode a value as if it were an address and the slashes and ampersands inside it are left alone, so the address splits at points where it was never meant to and the destination receives half a parameter.

Why %20 signs appear

Because an address may only carry a handful of characters, and the space is not one of them. When one that is not allowed has to go in, it is replaced by a percent sign followed by its number in hexadecimal. The space is character 32, which is 20 in hexadecimal; hence %20, and hence the name of the system: percent encoding.

With accents there is an extra step. The letter ñ has no number below 256, so it is first turned into UTF-8 bytes — ñ is two of them, C3 and B1 — and then each byte is written with its own percent: %C3%B1. The euro sign is three bytes and an emoji is four, which is why an emoji takes twelve characters once encoded. That is handled properly here; it is where quite a few tools fall over, stopping at the first 256 characters and returning nonsense the moment an accent shows up.

Seeing %20 in a URL is not an error: it is the correct way to write it, and the browser undoes it when displaying the page. You only see it when someone copies it into a place where nothing translates it back.

The + sign and the misunderstanding it drags along

In the query string — everything after the question mark — a plus sign means space. It comes from the format web forms use to send their data, and it is still alive across half the internet. Everywhere else in the address, a plus is a plus.

The trouble is that the function almost every tool uses to decode knows nothing about that: it returns the plus as it is. That is why you paste John+Smith and get John+Smith instead of John Smith. Here it is a checkbox, on by default because it is almost always what you want. And it works the other way round just as well: a plus that really is a plus is encoded as %2B, so C++ comes back intact even with the box ticked.

Encoding twice: where %2520 comes from

The percent sign is special too, so it has to be encoded itself: its code is %25. If you take a %20 — already an encoded space — and encode it again, the percent turns into %25 and you get %2520.

When it is opened, the browser undoes a single layer: where it should see a space it sees the literal text "%20", looks for a file that does not exist and returns an error. It happens when a link crosses two systems and each encodes it without checking whether it was encoded already. The tool detects it and says so, naming the exact sequence and what it was before. The fix is to decode until no sequences are left, or to encode the original only once.

Campaign links, and the detail that splits reports

The five UTM fields are the standard way of telling analytics where each visit came from, and every tool understands them with no configuration. Three matter nearly always — source, medium and campaign — and two are optional.

The mistake that ruins most reports is not spelling them wrongly: it is spelling them two different ways. Analytics is case-sensitive, so "Facebook" and "facebook" are different sources and the same campaign comes out as two rows you have to add up by hand. Same with spaces, which show up in the report as %20 or as plus signs. Both are flagged here before they happen, and there is a checkbox to normalise everything automatically.

One more detail: if the destination URL already carried campaign fields, they are replaced in place rather than added again. Pasting the same link twice is the usual way of ending up with two campaigns for one click.

The final link comes with a downloadable QR code, for a poster or a flyer. If you need something more elaborate — with a logo, colours, or a different kind of content — the site has a full QR code generator.

Domain names in disguise

A domain can be written in any alphabet, but underneath it travels converted into a form that starts with xn--. That is what lets españa.com exist, and also what lets someone register a domain that looks like a well-known brand using a letter from another alphabet that appears identical.

When the parser sees one of those, it translates it back and shows you what it actually says. It is a piece of information almost no tool gives, and it is welcome exactly when you are deciding whether to click a link.

What gets encoded and what does not

Every equivalence in these tables comes from the same engine the tool above uses, so they cannot contradict it. A dash in a column means that character is left alone in that mode.

Always encoded

CharacterNameAs a valueAs an addressWhy
Space%20%20Not allowed in an address. By far the most frequent case.
"Double quote%22%22Delimits attributes in HTML and would break the markup.
%Percent%25%25It is the system's own symbol: leave it and everything after it is misread.
< >Less than, greater than%3C %3E%3C %3EThey open and close tags.
{ } | \ ^ `Braces, pipe, backslash, caret, backtick%7B %7D %7C %5C %5E %60sameNever been allowed, even though some browsers tolerate them.
[ ]Square brackets%5B %5D%5B %5DReserved for modern network addresses, which go in brackets.
Line breakNewline%0A%0AIt would split the request in two.
TabTabulation%09%09Same as the line break.

Mode-dependent (the ones that give structure)

CharacterNameAs a valueAs an addressWhat it separates
/Slash%2F— left aloneThe folders in the path.
:Colon%3A— left aloneThe scheme from the rest, and the host from the port.
?Question mark%3F— left aloneWhere the query string begins.
#Hash%23— left aloneWhere the fragment begins.
&Ampersand%26— left aloneOne parameter from the next.
=Equals%3D— left aloneA parameter's name from its value.
+Plus%2B— left aloneIn a query it means space, so a real plus has to be encoded.
@At%40— left aloneThe user from the host.
; , $Semicolon, comma, dollar%3B %2C %24— left aloneReserved just in case; some systems use them as their own separators.

The five odd ones, and strict mode

CharacterNameNormalStrictWhen it matters
!Exclamation mark— left alone%21RFC 3986 treats them as reserved, but the function browsers ship leaves them through. It rarely matters and occasionally breaks something: a parenthesis inside a Markdown link splits it in half, and an apostrophe chokes some older parsers.
'Apostrophe— left alone%27
(Open parenthesis— left alone%28
)Close parenthesis— left alone%29
*Asterisk— left alone%2A

Never encoded, and always encoded

CharacterNameResultNote
a–z A–ZUnaccented letters— left aloneThese are RFC 3986's unreserved set: safe anywhere in an address and in any mode.
0–9Digits— left alone
- _ . ~Hyphen, underscore, dot, tilde— left aloneThe four signs that get away with it. That is why slugs are written with hyphens.
ñN with tilde%C3%B1Two bytes in UTF-8, two sequences.
á é í ó ú üAccented vowels%C3%A1…Same: two bytes each.
€Euro sign%E2%82%ACThree bytes.
🚀Emoji%F0%9F%9A%80Four bytes: twelve characters once encoded.

Frequently asked questions

Why do %20 signs appear in a URL?

Because an address only takes a handful of characters and the space is not one of them. When a forbidden one is needed it is written as a percent plus its number in hexadecimal: the space is 32, which is 20 in hex.

With accents there is an extra step: they are turned into UTF-8 bytes first and then each byte gets its percent, so ñ is %C3%B1 and an emoji takes twelve characters. Seeing a %20 is not an error: the browser undoes it when displaying the page, and you only see it where nothing translates it back.

What is the difference between encoding a value and a whole URL?

Whether the characters that give structure get encoded: colon, slashes, question mark, hash, ampersand and equals.

As a value everything is encoded and the result is no longer an address but text: that is what you need to put it inside another address's parameter, hence url=https%3A%2F%2F…. As a whole address those separators are respected and only forbidden characters are fixed: that repairs an address that already is one.

Why does %2520 appear and the link not work?

Because it is encoded twice. The percent is special too and encodes as %25: encode a %20 again and you get %2520.

Opening it, the browser undoes one layer, sees the literal text "%20" and looks for a file that does not exist. It happens when a link passes through two systems that both encode. The tool spots it and tells you what the sequence used to be.

Is a + sign a space or a plus?

It depends where it is. In the query string it means space, inherited from the format web forms use. Everywhere else, a plus is a plus.

The usual decoding function does not know that, which is why other tools hand you "John+Smith" where it said "John Smith". Here it is a checkbox, on by default. And a real plus is encoded as %2B, so C++ survives intact.

Which characters have to be encoded?

Unaccented letters, digits and four signs — hyphen, underscore, dot, tilde — never need it. The ones that give structure are encoded only inside a value. And anything that is not English is always encoded.

That leaves five odd cases — ! ' ( ) * — which RFC 3986 reserves but the browsers' function lets through; that is what strict mode is for. The full table sits just above these questions.

What are UTM parameters for?

So analytics knows where each visit came from, with no configuration. A flyer with a QR, a newsletter and an ad can all point at the same page, and without UTMs all three visits look identical in the report.

The detail that breaks most reports is that analytics is case-sensitive: "Facebook" and "facebook" are two sources and split the campaign in two. You are warned before it happens. The link comes with its QR code; for something more elaborate, the QR code generator.

What does the parser add over pasting the URL in the browser?

It opens it into pieces and lets you change them. Scheme, subdomain, domain, suffix, port, path and fragment separately, and the parameters in a table where they can be edited, added and removed, with the URL rebuilt instantly.

Two details: what you do not touch comes out exactly as it went in, with nothing re-encoded on its own; and if the domain travels in disguise as punycode — those addresses starting with xn-- — you are told what it really says.

Is the URL I paste sent to a server?

No. The encoding, the parsing, the campaign links and the QR code itself are all worked out inside your browser. There are no accounts, no database, and no request that carries your address anywhere. It matters because a URL carries session identifiers, internal paths, customer references or unpublished pages. Once the page has loaded, disconnect from the internet and check: it still works exactly the same.

Related tools