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.
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
-
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.
-
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.
-
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
- Putting one URL inside anotherA return link, a redirect after signing in, a call to a service. It travels as a value, so it has to be encoded whole.
- Making sense of an enormous linkThe kind that arrives by email with forty parameters. It opens up and shows in plain text what it carries, including the address hidden inside.
- Setting up a campaignThe five UTM fields in place, spelled the same way every time, so the report does not come out split in two.
- Changing a parameter and testingTweak an id, strip the tracking ones, add a debug flag, and take the finished URL with you.
- Checking whether a link is trustworthySee where it really goes before clicking, and whether the domain is spelled with letters from another alphabet to look like a familiar one.
- Fixing a link that will not openIt is nearly always an unencoded space, an accent, or double encoding. You can see at once which of the three.
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 thoseurl=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
| Character | Name | As a value | As an address | Why |
|---|---|---|---|---|
| Space | %20 | %20 | Not allowed in an address. By far the most frequent case. |
" | Double quote | %22 | %22 | Delimits attributes in HTML and would break the markup. |
% | Percent | %25 | %25 | It is the system's own symbol: leave it and everything after it is misread. |
< > | Less than, greater than | %3C %3E | %3C %3E | They open and close tags. |
{ } | \ ^ ` | Braces, pipe, backslash, caret, backtick | %7B %7D %7C %5C %5E %60 | same | Never been allowed, even though some browsers tolerate them. |
[ ] | Square brackets | %5B %5D | %5B %5D | Reserved for modern network addresses, which go in brackets. |
| Line break | Newline | %0A | %0A | It would split the request in two. |
| Tab | Tabulation | %09 | %09 | Same as the line break. |
Mode-dependent (the ones that give structure)
| Character | Name | As a value | As an address | What it separates |
|---|---|---|---|---|
/ | Slash | %2F | — left alone | The folders in the path. |
: | Colon | %3A | — left alone | The scheme from the rest, and the host from the port. |
? | Question mark | %3F | — left alone | Where the query string begins. |
# | Hash | %23 | — left alone | Where the fragment begins. |
& | Ampersand | %26 | — left alone | One parameter from the next. |
= | Equals | %3D | — left alone | A parameter's name from its value. |
+ | Plus | %2B | — left alone | In a query it means space, so a real plus has to be encoded. |
@ | At | %40 | — left alone | The user from the host. |
; , $ | Semicolon, comma, dollar | %3B %2C %24 | — left alone | Reserved just in case; some systems use them as their own separators. |
The five odd ones, and strict mode
| Character | Name | Normal | Strict | When it matters |
|---|---|---|---|---|
! | Exclamation mark | — left alone | %21 | RFC 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
| Character | Name | Result | Note |
|---|---|---|---|
a–z A–Z | Unaccented letters | — left alone | These are RFC 3986's unreserved set: safe anywhere in an address and in any mode. |
0–9 | Digits | — left alone | |
- _ . ~ | Hyphen, underscore, dot, tilde | — left alone | The four signs that get away with it. That is why slugs are written with hyphens. |
ñ | N with tilde | %C3%B1 | Two bytes in UTF-8, two sequences. |
á é í ó ú ü | Accented vowels | %C3%A1… | Same: two bytes each. |
€ | Euro sign | %E2%82%AC | Three bytes. |
🚀 | Emoji | %F0%9F%9A%80 | Four 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.