Encoder workbench
Base64, URL escapes, HTML entities and raw bytes, both directions, as you type. Nothing you paste here goes anywhere. Not even to us.
Type on the left and the right side keeps up.
BASE64 ENCODE 0 -> 0 BYTES
Base64, done in bytes
Your text becomes UTF-8 bytes first, and those bytes become base64. That matters. The browser's built-in btoa only accepts characters up to 255, so btoa("é") works by accident, btoa("€") throws, and btoa("😀") throws too. Encoding the bytes instead of the string is the fix, and it is what every other language does anyway.
base64url swaps + and / for - and _ and drops the = padding, so the result is safe in a URL or a filename. It is what JWTs use. Decoding accepts either alphabet, ignores whitespace, and forgives missing padding.
Files are read by your browser and never uploaded. Encode one and you get a data URI with its MIME type, ready to paste into an src or a stylesheet. Paste base64 in the other direction and download the bytes as a file; if it came with a data URI prefix the type is kept.
Two functions, one hard rule
encodeURIComponent escapes everything that has meaning in a URL, including /, ?, &, =, # and +. Use it for a value you are putting inside a URL: a search term, a redirect target, a filename in a path.
encodeURI leaves those alone so that a URL stays a URL. Use it on a whole address that merely has spaces or accents in it. Use it on a query value and you have just let a & split your parameter in two.
Decoding throws on a % that is not followed by two hex digits. This page tells you where. The + option is for form fields: browsers send spaces in application/x-www-form-urlencoded bodies as +, but decodeURIComponent does not know that.
Names where they exist, numbers where they do not
Encoding uses the named entity when HTML has one (é, —, €, the 252 names from HTML 4 that every browser has known for decades) and a numeric reference otherwise, decimal or hex, your call. The apostrophe is written ' rather than ' because old HTML parsers do not know the name.
Only the five that matter is the option you want when you are escaping text for an HTML page. &, <, >, " and ' are the only characters that can change the meaning of markup; everything else is safe to leave as UTF-8. Encoding accents into entities is a habit from the days before pages declared their charset.
Decoding understands all 2,231 named entities in HTML 5, plus decimal and hex references, because it asks the browser's own parser. Nothing is rendered or run; the text goes through an inert text field.
What the string actually is
A character is not a byte. In UTF-8 the letters you see on a keyboard are one byte each, é is two, € is three, and every emoji is four, so a 10-character string can be anywhere from 10 to 40 bytes. This view shows the bytes the other tabs are working from, as hex pairs and as octets of binary, with the count.
Swap the sides and it runs backwards: paste hex, with or without spaces or 0x, or paste binary octets, and get the text back. A byte that is not valid UTF-8 is shown as the replacement character and the reading line says so.
What stays here
Everything on this page is plain JavaScript in your browser: TextEncoder for the bytes, btoa and atob over those bytes for base64, encodeURIComponent and encodeURI for URLs, an inert text field for entities. There is no server doing the work, so there is nothing to send it to. Your text and your files are not stored, not logged, and are gone when you close the tab. The only thing this page records is that an encoding happened, and on which tab.
The options, the tab and the direction are remembered in this browser so the bench is set up the way you left it. The text is not.