Migrating Templates from Mandrill to SendGrid

Emil Ong
Haus Engineering Blog
4 min readApr 20, 2016
Christmas egg scene with Snoopy and Woodstock by Kevin Dooley is licensed under CC by 2.0

DISCLAIMER: I’m not endorsing moving from Mandrill to SendGrid. If you’ve decided to make this move or are just thinking about it, this post is here simply to let you know some of the technical implications.

Before you read the following, please read SendGrid’s migration guide. It’s an excellent introduction to the different ways that SendGrid behaves differently compared to Mandrill. This post addresses some additional issues that I came across with templates in particular which may be helpful for your app if you’re set up in a similar way.

Templating languages

In our app, we’re using templates for sending all our HTML transactional emails. We used Mandrill’s templating system for our HTML emails, injecting variables using Handlebars. Mandrill also has their own templating language, predating their Handlebars support. The Handlebars option is a great one since it allows some basic logic and is familiar to a lot of developers. Mandrill also includes some nice helpers.

SendGrid uses a different approach that AFAICT is just straight string substitution. Their documentation has examples showing adding *, -, %, and other separators as prefixes and/or suffixes on variables as they appear in the body of the template. Fortunately, we do pre-templating in our app before sending to the transactional service so all the logic is there and we didn’t have to make a big change. If you have complex logic in your templates, you may need to do the same.

CSS Inlining

Both Mandrill and SendGrid feature WYSIWYG and raw HTML editors for inputting templates. (They both also allow you to CRUD templates via their APIs.) One nice feature about Mandrill (which I’m not sure if they even mention?) is that they appear to post-process your HTML emails, inlining the CSS. As it turns out, you’ll need to do this if you actually want your styles to render in Gmail etc.

For better or worse, Mandrill’s post-processing allowed us to save our templates with CSS in <head><style> blocks, which is great for organization and readability, but didn’t occur to us as a problem for rendering until trying to import those same templates directly.

SendGrid does not do this for you, but it’s not too hard to do on your own using Juice or some other CSS inliner. If you’re using HTML in your template itself, you’ll need to pre-process it using an inliner before saving it to SendGrid. If you’re injecting HTML into the template from your app, make sure its CSS is inlined as well. This step might be a bit trickier, depending on the complexity of your styling given that you’re probably injecting HTML fragments. All of ours are explicitly inlined at the moment.

Images

There’s a lot to consider when using images in HTML emails, but I’ll just note here that both SendGrid and Mandrill offer image hosting. To move your images from Mandrill to SendGrid, you’ll need to upload them again into their WYSIWYG editor. You can do this in a throwaway template, switch the template to “Code” editing mode, then grab the URL from there and drop it into your template. If you have a lot of images and/or require more automated management, you may want to consider using another, external CDN.

Be careful when using Juice with an <img> tag as it may inline the image if it’s small enough. It delegates the inlining to a package called web-resource-inliner. You can tell it not to inline images at all. If you’re using the CLI, you can do that like so:

juice --web-resources-images 0 normalized.html inlined.html

Forcing HTML

In your API calls, SendGrid requires you to specify at least one of the “text” or “html” fields when sending an email, even for templates (unless I’m doing it wrong…). So what do send if all of your content is in the template and variables? Just send a space in the html field. Doing this will make SendGrid’s API accept the message and will select the HTML format for the template. If you send anything in the text field, SendGrid will send a text version.

Summary

I hope this post has helped in case you’ve run into any of these issues. To sum up:

  • SendGrid uses string substitution for templating, so pre-template in your app if required.
  • Inline your CSS.
  • Upload your images to some CDN (possibly SendGrid’s via its editor) if you were linking before.
  • Send a space (‘ ‘) in the html field.

If you’re interested in working with us, please check out our jobs page and get in touch!

--

--