Advertisement
  1. Web Design
  2. Email
  3. Email Design

Using Grunt to Make Your Email Design Workflow Fun Again

Scroll to top

Designing email is hard and archaic. Inlining CSS, table design, varying CSS support, multiple devices, multiple clients, the list is endless. In this tutorial I’ll explain how you can use Grunt to help automate and streamline your workflow.

Broken Email Design Workflow

Email design is a different workflow to web design. Often you’re designing a template in an isolated environment, with little to no dependencies or shared resources. You may be copying markup from one place (local, static) to another (ESP, codebase). It can be difficult to maintain your email templates, hard to keep them consistent and awkward to collaborate with team members, all while keeping in mind the various testing and inlining that needs to be done before they are sent.

One problem I’ve had in the past is every time I needed a new email template, I would take an existing template then make a few tweaks here and there. This would result in inconsistent emails across the product. Which is just bad practice.

Another issue I’ve come across is I think I’m done, so I put the template through a CSS inliner tool and hand it over to a developer, only for someone to request a change, or point out an error. The edit/inline/copy workflow then has to be repeated again and again.

Grunt to the Rescue

Nowadays I use Grunt to optimize my email design workflow. It helps with a few things:

  • It gives me a framework to work in, so I can use Sass and templating
  • It serves as a boilerplate for new emails
  • It helps make my emails consistent across a project
  • It automates the various tasks and tests I have to do for each email

What is Grunt?

Grunt is a task runner. It’s a Javascript file that runs the tasks you want it to run one after another. That list of things you need to do I just mentioned above? We can put those into a Grunt file and have it do all those for us. Perfect for running repetitive tasks.

To get Grunt up and running you’ll have to get your hands just a bit dirty with command line stuff and Javascript. But it’s very straight forward.

1. How to Get Grunt up and Running

Chris Coyier gives a really good tutorial on setting up Grunt for the first time. I’m going to run over the basics.

Grunt requires a couple of things to get going. Node, a package manager and a grunt file.

Install Node

Go to the Node site and follow the instructions to install. 

Create package.json in Your Project’s Directory

Create a new folder (e.g. called email) then create a file named package.json.

Paste this JSON into the file.

1
{
2
  "name": "emailDesign",
3
  "version": "0.1.0",
4
  "devDependencies": {
5
    "grunt": "~0.4.5"
6
  }
7
}

Here we’re telling the node package manager to use Grunt, version 0.4.5 or above.

NPM install

Now in order to install the above version of Grunt, go to your project’s directory in command line and enter:

1
npm install

When you run this command you’ll notice a node_modules folder appear.

Install Grunt Command Line Interface

Still in your email directory, run the following command:

1
npm install -g grunt-cli

Note: you may need to prepend this command with sudo  if you’re asked to run it as root/Administrator. 

Having done that, we can now type Grunt commands into the command line.

Create your Gruntfile.js

Create a file called Gruntfile.js in your project folder and include the following JavaScript:

1
module.exports = function(grunt) {
2
3
    grunt.initConfig({
4
      pkg: grunt.file.readJSON('package.json')
5
    });
6
7
    grunt.registerTask('default');
8
9
};

This is the bare bones of what’s needed for Grunt to work. Now to add more exciting stuff.

2. Add the Tasks to Grunt

Let’s start off with something simple, but vital: Inlining CSS. Let’s say we have an email template, with CSS in the head. CSS in the head is easy(ish) to maintain, but the template that we actually want to send should have CSS inlined.

Create the HTML Template

We’re going to use a fairly basic HTML email with the CSS in the head. Save the following markup as email.html in your project’s directory.

1
<html>
2
<head>
3
  <style>
4
  body{
5
    background:#f1f1f1;
6
    font-family: Helvetica;
7
  }
8
  .container{
9
    background:#fff;
10
    border:1px solid #eee;
11
    width:500px;
12
    padding:20px;
13
    margin:20px auto;
14
  }
15
  h1{
16
    font-size:32px;
17
    text-align:center;
18
    font-weight:400;
19
  }
20
  </style>
21
</head>
22
23
<body>
24
  <div class="container">
25
    <h1>Hello world!</h1>
26
    <p>This is an email template.</p>
27
  </div>
28
</body>
29
</html>

Install the CSS Inliner Task

Next we’re going to use a CSS inliner task to place each style rule inline on the HTML elements themselves. I like this inliner as it doesn’t require other dependencies. Head back to your command line and run this:

1
npm install grunt-inline-css --save-dev

This will add the grunt-inline-css task to your npm_modules folder, as well as the package.json file.

Add the Task to Your Gruntfile

Next add the task to your Gruntfile.js using this snippet, above where you see grunt.registerTask('default');

1
grunt.loadNpmTasks('grunt-inline-css');

Then add in your config options, within the grunt.initConfig() method:

1
inlinecss: {
2
    main: {
3
        options: {},
4
        files: {
5
            'email-inlined.html': 'email.html'
6
        }
7
    }
8
}

Here we're telling inlinecss to find the file named “email.html” and output “email-inlined.html”. Finally, we call it from the grunt default task:

1
grunt.registerTask('default',['inlinecss']);

The Final Gruntfile

Your Gruntfile should now look something like this:

1
module.exports = function(grunt) {
2
3
    grunt.initConfig({
4
      pkg: grunt.file.readJSON('package.json'),
5
6
      inlinecss: {
7
        main: {
8
          options: {
9
          },
10
          files: {
11
            'email-inlined.html': 'email.html'
12
          }
13
        }
14
      }
15
16
    });
17
18
    grunt.loadNpmTasks('grunt-inline-css');
19
20
    grunt.registerTask('default',['inlinecss']);
21
22
};

Run Grunt

Returning once again to the command line, type grunt and enter to run it. 

You should now be left with an email-inlined.html file that has the css inlined. If you open both HTML files in your browser they should look the same.

Email Design Tasks

With any luck that will have convinced you of the powers of Grunt in automating your email design workflow. What’s more, following that introduction has given you the framework to go even further.

What other email design tasks might you automate?

  • Compile CSS (if using SASS or Less)
  • Inline CSS
  • Compile HTML templates (if using layouts and partials)
  • Previewing in the browser
  • Previewing in mail clients
  • Testing with email testing apps (Litmus, Email on Acid)
  • Uploading assets to a publicly available CDN
  • Adding UTM tracking tags to links
  • …the list goes on

My Email Design Gruntfile

This is the Gruntfile, open-sourced on GitHub, that I use quite often. Let’s take a look at the individual tasks to see what’s actually going on.

1. Sass/SCSS

I like to manage my CSS using SCSS, so the first thing I get Grunt to do is compile the main SCSS file.

2. Assemble HTML

Assemble is a static site generator. It compiles the HTML by bringing together the main layout template(s) and the content for each email.

3. Inline CSS

I’m using premailer to inline CSS. If you’re wondering why I’m not using the inliner from above, I found that premailer has better support for media queries. For media queries to work, we want them to be left alone in the head, not inlined. 

Note: premailer has dependencies which also need to be installed, including Ruby and a couple of gems.

4. Sending a Test Email

To send an email to an inbox I’m using Mailgun's API. This sends the outputted HTML email to my inbox so I can see it for myself in whichever client I choose.

This is also a useful way to send your template to Litmus if you want to preview it in other email clients. Doing so is a matter of changing the recipient.

5. CDN

This is handy if you’re sending transactional emails and need to store image assets somewhere. If you’re using an ESP (Email Service Provider) to send your emails there’s a good chance they store your image assets for you, so it’s not an issue in this case.

Running the Tasks

To run the tasks we have a number of command options.

  • grunt runs the default task. This includes compiling Sass, assembling templates and inlining the CSS. You can then open up the output in your browser.
  • grunt send --template=MY_TEMPLATE.html will run the above tasks, as well as sending out the email template you specify. Remember to update the Mailgun settings in Gruntfile.js.
  • grunt cdnify will again run the default tasks, but will also upload any local image assets, then replace the file paths with the CDN path.
  • Note you can also combine tasks e.g. grunt cdnify send —template=MY_TEMPLATE.html

More Tasks!

There are more tasks you might want to add to aid your process, or you may want to remove some. Head over to Grunt's plugin directory to find the tasks that help your workflow.

Transactional Email Templates

Here are some templates I prepared earlier.

Using the workflow and Gruntfile outlined above, I open-sourced a handful of transactional emails for dev teams to use. Feel free to make use of them as is, or use them as a boilerplate for your own email designs.

Useful Email Design Resources

Conclusion

Many tasks associated with email design can be arduous and awkward. Let Grunt do the hard work for you and you’ll find the whole process much more enjoyable!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.