Search code examples
node.jsemailoutlookejs

base64 images not displaying in Outlook when using ejs + emailjs


I'm using a mix of ejs and emailjs to send out emails in my node.js app when various events happen. I'd like to embed a base64 image (a small logo) into the email when it sends, but both Outlook and Gmail (plus Inbox by Google) fail to render the image.

I'm using this bit of code to find the mime type of the image and put together the base64 string:

MyApp.prototype.ImageToBase64 = function(image) {
  var mime = require("mime")
  file = fs.readFileSync(__dirname + "/images/" + image, { encoding: 'base64'})
  return 'data:' + mime.lookup(image) + ';base64,' + file;
}

That works great, because I'm able to copy and paste that resulting string right into my browser and see the image. But when I send the email via emailjs, Outlook converts the +s to +. When I "View Original" in Gmail, the base64 is split up into 'chunks'. Each chunk is on a newline and each line ends with a =. If I take Gmail's version and remove the = and newline then paste it into my browser, the whole picture loads perfectly, but it just refuses to load anywhere else, regardless of whether the user is in my contact list or not.

Here's the code I'm using to send the email:

// Host, username, password and SSL (false) all set above here
server.send({
    text: myTemplate,
    from: "[email protected]",
    to: "[email protected]",
    subject: "Testing",
    attachment: [
     {data:myTemplate, alternative:true}
    ]
  })

And the template looks like this (truncated, as the other bits aren't important):

  <body>
    <p><img src="<%- ImageToBase64("logo.png") %>"></p>
    <h1><%= Name %> has been triggered</h1>
    <p><%= Name %> has been triggered. It was triggered on <%= TheDate %></p>

Any hints?

EDIT: I tried setting the headers in the "attachment" property, but with no luck


Solution

  • Outlook uses Word to render the images, and Word does not support embedded (src="data:image") images.

    You need to attach the image as a file and set the Content-ID MIME header to the value matching the cid attribute on the image (<img src="cid:xyz">) in the HTML body.