To encode and decode strings to Base64 in JavaScript, you can use the built-in btoa()
(encode) and atob()
(decode) functions. However, these methods only handle Latin1 characters (ASCII) natively. For Unicode strings (e.g., emojis, accents), you need additional steps to encode/decode UTF-8 properly. Below are detailed solutions with examples:
1. Basic Encoding/Decoding (ASCII/Latin1)
For simple ASCII strings (no Unicode):
Encode a string to Base64:
const text = "Hello World!";
const encoded = btoa(text); // "SGVsbG8gV29ybGQh"
Decode a Base64 string:
const base64 = "SGVsbG8gV29ybGQh";
const decoded = atob(base64); // "Hello World!"
2. Handling Unicode Strings (UTF-8)
To support characters like Ç
, ñ
, or emojis (🦄), use TextEncoder
and TextDecoder
:
Encode a Unicode string to Base64:
function encodeBase64(str) {
// Convert UTF-8 string to a Uint8Array
const encoder = new TextEncoder();
const data = encoder.encode(str);
// Convert bytes to a binary string and encode as Base64
const binaryString = String.fromCharCode(...data);
return btoa(binaryString);
}
const unicodeText = "Hello, 世界! 🦄";
const encodedUnicode = encodeBase64(unicodeText); // "SGVsbG8sIOS4lueVjCEg8J+ajA=="
Decode a Base64 string to Unicode:
function decodeBase64(base64) {
// Decode Base64 to a binary string
const binaryString = atob(base64);
// Convert binary string to Uint8Array
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
// Decode UTF-8 bytes back to a string
const decoder = new TextDecoder();
return decoder.decode(bytes);
}
const decodedUnicode = decodeBase64(encodedUnicode); // "Hello, 世界! 🦄"
3. Edge Cases
Empty String:
const emptyEncoded = btoa(""); // ""
const emptyDecoded = atob(""); // ""
Special Characters:
const textWithSymbols = "Password!@#$%^&*";
const encodedSymbols = btoa(textWithSymbols); // "UGFzc3dvcmQhQCMkJV4mKg=="
const decodedSymbols = atob(encodedSymbols); // "Password!@#$%^&*"
4. Node.js Compatibility
In Node.js, use the Buffer
class instead of btoa
/atob
:
// Encode
const encoded = Buffer.from("Hello World!", 'utf8').toString('base64');
// Decode
const decoded = Buffer.from(encoded, 'base64').toString('utf8');
5. URL-Safe Base64
Replace +
with -
and /
with _
for URL-safe encoding:
function encodeUrlSafeBase64(str) {
const base64 = encodeBase64(str);
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}
function decodeUrlSafeBase64(base64) {
// Replace URL-safe characters and add padding
let safeBase64 = base64.replace(/-/g, '+').replace(/_/g, '/');
while (safeBase64.length % 4 !== 0) {
safeBase64 += '=';
}
return decodeBase64(safeBase64);
}
const urlSafe = encodeUrlSafeBase64("Data? Yes!"); // "RGF0YT8gWWVzIQ"
const original = decodeUrlSafeBase64(urlSafe); // "Data? Yes!"
Key Notes
btoa()
andatob()
: Only handle Latin1 characters (no Unicode).- UTF-8 Support: Use
TextEncoder
andTextDecoder
for Unicode. - Node.js: Replace
btoa
/atob
withBuffer
. - URL Safety: Adjust characters for URLs or filenames.
Full Example Workflow
// Encode
function encodeBase64(str) {
return btoa(
String.fromCharCode(...new TextEncoder().encode(str))
);
}
// Decode
function decodeBase64(base64) {
const bytes = Uint8Array.from(atob(base64), c => c.charCodeAt(0));
return new TextDecoder().decode(bytes);
}
// Test with emojis and accents
const text = "Héllø, 𝓦orld! 👋";
const encoded = encodeBase64(text); // "SMOpbGzDuCwg8J+aksOybGTDpyEg8J+Piw=="
const decoded = decodeBase64(encoded); // "Héllø, 𝓦orld! 👋"
This approach ensures compatibility with all modern browsers and handles Unicode seamlessly!