Equivalent of Node's Buffer function in Retool

I need to convert a UTF-8 string to base64 for consumption by gmail's API. (Use case is similar to this one.)

Normally in Node, you'd do this with the server-side Buffer() function, like this:

const encodedMessage = Buffer.from('Hello world! 🙂').toString('base64');

Unfortunately, Retool's JS browser environment doesn't support Buffer(). Retool scripting does support btoa(), but unfortunately btoa() can't handle non-ASCII characters so it won't solve for my use case:

const encodedMessage = btoa('Hello world!'); // ok
const encodedMessage = btoa('Hello world! 🙂'); // crashes due to non-ASCII emoji

So my question is: how can I encode a UTF-8 string into base64 in Retool?

Note: This question has been asked already, and the suggested solution was to use this library that ports Buffer() to the browser. But unfortunately the CDN link that's given in the answer (https://cdn.jsdelivr.net/npm/buffer@6.0.3/index.min.js) isn't in UMD format, so it's not usable as a Retool library. I haven't had any luck yet in finding a UMD-friendly buffer library.

Here's one workaround:

function utf8_to_b64(str) {
  return btoa(unescape(encodeURIComponent(str)))

function b64_to_utf8(str) {
  return decodeURIComponent(escape(atob(str)))

I think there's some room for ambiguity in implementation here since it's not obvious how to map a multi-byte character into base64. However this implementation seems to do the same thing as Buffer.toString.

^ There is also a couple other approaches here that don't require use of the deprecated escape/unescape functions.

1 Like

Hey bca — thanks so much for the quick reply! Your suggestion is great and it does in fact solve my problem. I've marked it as the solution. Thanks so much!

Worth noting that I had seen this solution online and started implementing it, but that Retool's UI marks the unescape function as "not defined" in my browser (see screencap).

Screen Shot 2022-12-08 at 7.45.41 AM

As a result, while I'd tried writing up this solution, I'd never bothered to actually run it. But it does in fact work despite the UI suggesting otherwise.

Thanks again!

Got it, this looks like a bug to me -- will file a bug report!

1 Like