Base64 encoding is one of those small developer tasks that looks simple until you hit Unicode characters, files, APIs, or URL-safe formats.
In JavaScript, many tutorials show this:
btoa("Hello World");
And yes, it works.
But only for simple ASCII text.
Once you try to encode something like:
"Café 🚀"
you may run into errors or broken output.
In this guide, we’ll cover how Base64 encoding works in JavaScript, when btoa() is enough, when it is not, and how to encode text, Unicode, files, images, and URL-safe Base64 correctly.
You can also test examples quickly with EncodingBase64, a free browser-based Base64 encoder for text, files, images, URL-safe Base64, hex, and URL encoding.
What is Base64 encoding?
Base64 is a way to represent binary data using readable ASCII characters.
It is commonly used when binary data needs to travel through systems that expect text, such as:
- APIs
- JSON payloads
- email attachments
- HTML/CSS data URIs
- authentication headers
- embedded images
- configuration files
For example:
Hello World
becomes:
SGVsbG8gV29ybGQ=
Base64 does not encrypt data. Anyone can decode it.
It only changes the representation of the data.
Basic Base64 encoding with btoa()
JavaScript includes a built-in function called btoa().
Example:
const text = "Hello World";
const encoded = btoa(text);
console.log(encoded);
// SGVsbG8gV29ybGQ=
To decode it back:
const decoded = atob(encoded);
console.log(decoded);
// Hello World
This is fine for basic ASCII strings.
But there is a problem.
The Unicode problem with btoa()
Try this:
const text = "Café 🚀";
const encoded = btoa(text);
console.log(encoded);
Depending on the environment, you may get an error like:
InvalidCharacterError
Why?
Because btoa() expects a binary string where each character is in the Latin-1 range. It does not directly support full Unicode text.
Modern apps often deal with:
- accented characters
- Arabic
- French
- Spanish
- German
- Portuguese
- emojis
- non-Latin scripts
So we need a safer method.
Unicode-safe Base64 encoding
Use TextEncoder to convert the string into UTF-8 bytes first.
function encodeBase64Unicode(text) {
const bytes = new TextEncoder().encode(text);
let binary = "";
bytes.forEach((byte) => {
binary += String.fromCharCode(byte);
});
return btoa(binary);
}
console.log(encodeBase64Unicode("Café 🚀"));
// Q2Fmw6kg8J+agA==
Now the Unicode string is safely converted to UTF-8 before Base64 encoding.
Unicode-safe Base64 decoding
To decode it back properly, use TextDecoder.
function decodeBase64Unicode(base64) {
const binary = atob(base64);
const bytes = Uint8Array.from(binary, (char) => {
return char.charCodeAt(0);
});
return new TextDecoder().decode(bytes);
}
const encoded = encodeBase64Unicode("Café 🚀");
const decoded = decodeBase64Unicode(encoded);
console.log(decoded);
// Café 🚀
This is safer for real-world text.
Encoding a file to Base64 in JavaScript
For files, you can use FileReader.
Example with an HTML file input:
<input type="file" id="fileInput" />
const input = document.getElementById("fileInput");
input.addEventListener("change", () => {
const file = input.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = () => {
console.log(reader.result);
};
reader.readAsDataURL(file);
});
The result will look like this:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
This is called a data URI.
It includes:
data:[mime-type];base64,[base64-data]
For example:
data:image/png;base64,iVBORw0KGgo...
If you only want the raw Base64 part, remove everything before the comma:
const dataUrl = reader.result;
const rawBase64 = dataUrl.split(",")[1];
console.log(rawBase64);
Encoding an image to Base64
Images are one of the most common Base64 use cases.
You might encode images to Base64 when:
- embedding a tiny icon in HTML
- storing a small image in JSON
- sending an image through an API
- generating previews
- creating CSS background images
Example HTML output:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." alt="Example" />
Example CSS output:
.icon {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...");
}
This is useful for small images.
But be careful: Base64 increases file size, so it is usually not ideal for large images.
For quick browser-based image conversion, EncodingBase64’s Image to Base64 tool can convert images into raw Base64, data URI, HTML, CSS, or Markdown formats.
What is URL-safe Base64?
Standard Base64 uses characters like:
+
/
=
These characters can be problematic in URLs.
URL-safe Base64 replaces:
+ with -
/ with _
Padding = may also be removed in some systems.
Example helper:
function toBase64Url(base64) {
return base64
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/g, "");
}
const encoded = encodeBase64Unicode("Hello World");
const urlSafe = toBase64Url(encoded);
console.log(urlSafe);
// SGVsbG8gV29ybGQ
To convert Base64URL back to standard Base64:
function fromBase64Url(base64Url) {
let base64 = base64Url
.replace(/-/g, "+")
.replace(/_/g, "/");
while (base64.length % 4 !== 0) {
base64 += "=";
}
return base64;
}
Base64URL is commonly used in:
- JWTs
- URL tokens
- authentication flows
- compact identifiers
- web-safe encoded data
Common Base64 encoding mistakes
1. Thinking Base64 is encryption
Base64 is not secure. It is reversible.
Do not use it to protect passwords, API keys, or private data.
2. Using btoa() directly with Unicode
This can break:
btoa("Café 🚀");
Use TextEncoder instead.
3. Using standard Base64 in URLs
Standard Base64 can contain +, /, and =. Use Base64URL when the value needs to go inside a URL.
4. Encoding large images unnecessarily
Base64 is usually better for small assets, not large files.
5. Forgetting the MIME type for images
For browser display, this:
iVBORw0KGgo...
may not be enough.
You often need:
data:image/png;base64,iVBORw0KGgo...
Quick answer
Use btoa() only for simple ASCII text.
For Unicode-safe Base64 encoding in JavaScript, convert text to UTF-8 bytes first using TextEncoder, then encode those bytes with btoa().
For files and images, use FileReader.readAsDataURL().
For URLs, convert standard Base64 into Base64URL by replacing + with -, / with _, and optionally removing = padding.
Final thoughts
Base64 encoding is simple in theory, but real-world usage gets more complex when you deal with Unicode, files, images, URLs, and APIs.
For quick testing, debugging, and conversion, a browser-based tool like EncodingBase64 can save time because you can encode text, files, images, URL-safe Base64, hex, and URLs without setting up code.
The key rule to remember:
Base64 is an encoding format, not a security feature.
Use it when you need text-safe data representation, not when you need encryption.
Top comments (0)