Leveraging ArrayBuffer to Convert Images to Base64 for Email Notifications
Posted by Nuno Marques on 14 Dec 2024
When building dynamic web applications like Bokkah, efficiently handling image data is crucial, especially when integrating features like sending email notifications for friend requests, invitation confirmations, or accepted requests. Inline Base64-encoded images in <img src="">
attributes can make these emails visually appealing without external hosting dependencies.
In this article, we’ll explore how ArrayBuffer
can be utilized to correctly fetch an image and encode it to a valid Base64 string, addressing common pitfalls.
Why Use ArrayBuffer?
ArrayBuffer
provides a mechanism to handle raw binary data. It enables fetching an image, decoding it into binary, and encoding it back into Base64—a format suitable for embedding directly in HTML or CSS.
The Problem with Base64 Conversion
An improperly implemented Base64 conversion can result in broken or unreadable images. Common mistakes include:
- Skipping the
Content-Type
or using incorrect MIME types. - Encoding improperly parsed binary data.
- Failing to handle fetch errors gracefully.
Correct Implementation
Here’s an improved utility function to fetch an image and convert it into a Base64-encoded string. This addresses issues like MIME type consistency and ensures valid encoding.
Working Code Snippet
import fetch from 'node-fetch';
// Function to fetch an image and convert it to Base64
export const fetchImageAsBase64 = async (imageUrl) => {
try {
const response = await fetch(imageUrl);
if (!response.ok) {
throw new Error(`Failed to fetch image: ${response.statusText}`);
}
// Read image as ArrayBuffer
const arrayBuffer = await response.arrayBuffer();
const base64Image = Buffer.from(arrayBuffer).toString('base64');
// Get MIME type dynamically
const mimeType = response.headers.get('content-type');
if (!mimeType.startsWith('image')) {
throw new Error(`The URL provided is not an image: ${mimeType}`);
}
// Return Base64-encoded string with MIME type
return `data:${mimeType};base64,${base64Image}`;
} catch (error) {
console.error(`Error fetching or converting image: ${error.message}`);
throw error;
}
};
// Example usage
(async () => {
try {
const imageUrl = 'https://example.com/path-to-image.jpg';
const base64String = await fetchImageAsBase64(imageUrl);
console.log(base64String); // Embed in <img src=""/>
} catch (error) {
console.error(error.message);
}
})();
Key Improvements in This Implementation
- Dynamic MIME Type Handling: The function detects the content type from HTTP headers, ensuring accurate encoding.
- Error Handling: Gracefully handles errors such as network issues or non-image URLs.
- Compatibility: Works with server-side environments like Node.js and ensures valid Base64 encoding using
Buffer
.
Practical Use Case
Imagine sending an email notification for a new friend request:
<!DOCTYPE html>
<html>
<body>
<h1>You Have a New Friend Request!</h1>
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..." alt="User Image">
</body>
</html>
Replace the src
attribute dynamically with the Base64-encoded string generated by the utility function.
Conclusion
Using ArrayBuffer
for binary data processing and encoding is a robust approach to embedding images in email templates. By following the improved function above, you can ensure seamless integration of inline images for email notifications, enhancing user experience.