Email is our primary form of communication with Code School customers, so we take it pretty seriously. We send a fair amount of emails, all of which fall into two distinct categories: promotional emails (announcing course releases, special offers, etc.) and transactional emails (welcoming new users, directing users through Code School, giving account updates, etc.)
Every email requires copywriting, design, and implementation. Implementation could be as simple as writing HTML/CSS and sending via MailChimp. Other times, it could require a developer to hook up data from the Code School app and trigger sending via Mandrill. Either way, we discuss the purpose behind an email, collaborate on copy, and then request work from designers and developers as necessary. For the past year and a half, I have been the primary person doing the HTML/CSS portion. I have learned so much, both in collaborating with the team and in building emails.
We send one to five promotional emails a month and have between 30 and 40 transactional emails that are set up at any given time. Every email is an individual HTML file that needs to exist in the service that sends it, in our case MailChimp and Mandrill. You can use their builders and editors to create and organize everything, but I’ve found working off-line to be more efficient.
Technical Problems and Solutions
Beyond figuring out the right messaging, there are technical problems involved with handling this many emails. Email clients have not evolved with web standards, so the tools are somewhat limiting as well. In regular front-end work, I take for granted that I won’t have to repeat things like headers and footers in every page that I create.
After the first time of updating multiple emails with changes to the footer, I sought a solution for automating that. Time invested in tooling can be a tough sell in some organizations. We’re encouraged to do it because time invested in automating menial tasks pays off in time to think about that which can’t be automated.
A static site generator was able to alleviate the bulk of the problems that I was facing. I chose Jekyll after trying a few. Below are some of the problems I’ve come across, and ways Jekyll offered solutions.
Problem: On occasion, you will need to update every email that you are currently sending. (Think site redesigns, logo updates, social media links, etc.) In my research I haven’t found a service that allows for partial templates, so each email is a unique HTML file. This means that while every email that we send has the same header and many have the same footer, that header and footer code has to be a part of every HTML file. If you’d like to add or change something, the code has to be changed in every file individually.
Solution: Static site generators allow for layouts and includes, so making updates to every file can be done from a single place. Change a link in one file, hit save, and it outputs every file that has that link. You still have to paste all of those files into the service, so this solution is better but not perfect.
Some changes can be done without code, so we store global assets on our own CDN. If our logo or social media logos change, they can be updated in S3 without touching HTML.
Inline Styles Add Redundancy
Problem: Many email clients will not process CSS that is included in the head of an email, which means that CSS has to be inline. Cascading styles are also not well supported in older clients, so nested tables require duplication of styles as well. On top of this redundancy, there’s also the use of HTML tables which add complexity and otherwise unnecessary code. Older email clients do not support CSS positioning, so tables are a necessary evil.
Solution: One of the best ways to reduce redundancy is to store blocks of code as a variable. Jekyll uses Yaml front matter, which can be used to declare variables. I use these to set styles for tables, type, colors, and spacing. This needs to be combined with a code style guide that uses the variables in order to work well. The combo of those two allows for rapidly changing email appearance and reduction of overall code. A bonus of front matter in this scenario is that it is intended to be used for meta information, which can display details about an email and organize them locally.
To write the bloated table code as succinctly as possible, I use Haml. While you don’t need a static site generator for this, there is a Jekyll plugin that handles the preprocessing of the Haml.
Problem: As a team, we recently did a review of every email that we send. Since they have different purposes and content, they are sent via different services. Some files are in MailChimp, some are in Mandrill, and some receive small blocks of code from the Code School app. In order to follow through a flow of emails, you would have to toggle back and forth between the two services and view code in your app.
Solution: The beauty of building offline is that it keeps all of your files in one place. As a team, we can review emails in a flow pretty easily using Jekyll’s local server. It does add complexity to copy changes, in that we typically do them offline and then update the file in the service. The benefit to this is that we keep the whole system in a GitHub repo, so anyone can pull and have all of the emails. While we’re completely happy with MailChimp and Mandrill, Jekyll allows us to easily move templates to other services when necessary. We had to do this for a few recent emails during some Stripe integrations.
The meta information from the front matter comes in really handy for this part. We can display anything that we like on the landing page and create custom views with information about the email itself.
Why just blog about your tools when you can share them? I started a repo called Emayll with the basic organization set up. It’s documented and has some dummy files to put in your own code. In there, you’ll find an explanation of the reasons behind code decisions and how to customize for your needs through variables. In my next post, I’ll break down getting started with a base layout and templates.
Finally, I thought it would be good to share all of the other tools that go into this workflow. We use: Google Drive for planning and copy, Photoshop and Illustrator for design assets, Atom editor for markup, and personal devices combined with Litmus for testing.