A Workflow That Takes The Pain Out Of (Responsive) HTML Email Development (Using Laravel and Gulp)

Published: February 23, 2015

Tags:

I built a SaaS app called Domain Clamp which monitors domain and SSL certificates and sends you notifications before anything expires. If you've ever been blamed (e.g. by a client) for letting a domain you don't own expire, check it out »

Most front end developers would probably not list coding HTML emails as one of their favorite activities. From table based layouts, to inline styles, to popular email clients that still use Microsoft Word as a rendering engine it is understandable that HTML email development is generally considered a nightmare. Fortunately, starter templates and build tools make the process a lot less painful. In this post I'll outline a workflow I set up on a recent project that made HTML email development downright fun.

No Need To Reinvent The Wheel

HTML email is hard. (If you were a psycho) You could try to build your own templates from scratch, but why reinvent the wheel when Mailchimp has released an open source library of awesome starter email templates. The base_boxed_basic_query template is a simple template that offers a perfect starting point for transactional HTML emails.

Mailchimp's base_boxed_basic_query template out-of-the-box

If you're working in Laravel go ahead and put this template into your app/views/emails directory.

Customization

Once you've placed the template into your email directory turn it into a layout that can be used for all your email templates. Update the code starting at line 477 as follows:

<table border="0" cellpadding="0" cellspacing="0" width="100%" id="templateBody">
    <tr>
        <td valign="top" class="bodyContent" mc:edit="body_content">
            @yield('content')
        </td>
    </tr>
</table>

Then, all your emails will extend that layout:

@extends('emails.build.email_layout')

@section('content')

<!-- Your content goes here -->
	
@stop

The Build Step

Before sending your emails you'll want to run them through a build tool to inline the CSS. The reason for this is that some email clients, most notably Gmail strip style tags out of the head. With Gulp, gulp-inline-css is the most popular option, however I have had problems using this plugin with Laravel as demonstrated below:

Before...

<p>Dear {{ $person->user->firstname }},</p>

After...

&lt;p&gt;Dear {{ $person-&amp;gt;user-&amp;gt;firstname }},&lt;/p&gt;

As a result, I've implemented the gulp-mc-inline-css plugin which calls the Mailchimp API to inline the CSS. However, I have an open issue and pull request on that repo to give the implementor the ability to set strip_css to false. This is necessary as without it, media queries will be stripped out and the email will lose it's resposiveness. In the meantime go ahead and use my fork of the repo. Here's how your package.json will look...

{
  "name": "email-workflow",
  "version": "0.1.0",
  "devDependencies": {
    "gulp": "^3.8.10",
    "gulp-mc-inline-css": "https://github.com/mpchadwick/gulp-mc-inline-css/tarball/master"
  }
}

Your gulpfile will look like this...

var gulp = require('gulp'),
mcInlineCss = require('gulp-mc-inline-css'),
config = require('./gulp_config.json');

gulp.task('mc-inline-css', function() {
	return gulp.src('./app/views/emails/*')
		.pipe(mcInlineCss(config.MC_APIKEY, false))
		.pipe(gulp.dest('./app/views/emails/build'));
});

The Send

In my app, Mandrill is being used to handle the send. However, Laravel offers great documentatation on it Mail class and feel free to use whichever driver you prefer.