How to Fix JavaScript btoa() "outside of the Latin1 range" Error?

Why Does This Happen?

The JavaScript btoa() method is commonly used for converting binary strings into Base64-encoded ASCII strings. However, it comes with a limitation — it only works well with characters that fit into a single byte (8 bits), typically those found in the ASCII or Latin-1 character sets. When you try to encode multibyte characters (like emojis or certain language characters) that go beyond this single-byte range, the btoa() method throws an error:

// ES5+
// Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
btoa('🦊');

// Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
btoa('こんにちは');

In this example, attempting to encode a fox emoji and a Japanese greeting using btoa() results in a DOMException due to characters being beyond the Latin-1 character set range.

This error occurs because the btoa() function expects characters within the ASCII or Latin-1 range (where Latin-1 includes the first 128 characters of ASCII and adds 128 additional characters, such as accented letters and symbols used in Western European languages). Understanding this limitation is crucial when working with btoa() to ensure compatibility with the expected character set.

How to Fix the Issue?

You can fix this issue by creating a custom function, like the following, to handle multibyte strings before passing them to the btoa() function:

function toBinaryStr(str) {
  const encoder = new TextEncoder();
  // 1: split the UTF-16 string into an array of bytes
  const charCodes = encoder.encode(str);
  // 2: concatenate byte data to create a binary string
  return String.fromCharCode(...charCodes);
}

console.log(btoa(toBinaryStr('🦊'))); // '8J+mig=='
console.log(btoa(toBinaryStr('こんにちは'))); // '44GT44KT44Gr44Gh44Gv'
console.log(btoa(toBinaryStr('foobar'))); // 'Zm9vYmFy'

In this function, TextEncoder.encode() converts the UTF-16 encoded string into a Uint8Array of bytes (UTF-8 encoding), and then these bytes are concatenated to create a binary string that works seamlessly with the btoa() method for Base64 encoding.


This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.