Setting Up HTML Emails in Rails

21 06 2012

A few weeks ago we decided to step up our email game. We had just received the masterclass in designing emails from Justine (@meladorri) and were about to launch our free plan, so the timing seemed right. It’s not that they looked sooo bad in the past, but we wanted a more unified theme that could be used for our many purposes (appearance and design is more of Joe’s area, so I’ll let him write more on that).

We send two types of emails – some that are general reference and informational (think newsletters) that we use email marketing tools like MailChimp and Pardot for, and some that are more personalized or time-sensitive for our customers (think overage alerts) that are sent via Rails.  So the challenge was two-fold – get the emails looking right in an email marketing tool, but also make sure they looked consistent coming out of Rails.

After Joe toiled on a beautiful, table-based layout (you have to use tables for good looking email, it’s terrible) and added it to our email marketing software without much trouble, the next challenge was porting that to the system-based emails.

Long story short – sending out HTML email is pretty tricky. There are some best practices for creating HTML emails (examples: NetTuts, MailChimp, and pretty much anything by Litmus ) but all of them involve painful stuff like inline styling and duplicate code. After much painful research and experimentation, I’ve got a few tips to help set up AND maintain great looking emails in Rails. It relies on a few gems and some basic Rails functionality, but it’s guaranteed to make your email life a lot easier.

Step 1: Set up the mailers
The first thing you need to do is set up Mailers and Views for the email you’d like to send out. There are much better tutorials around this part than I can provide, and they are fairly straightforward to generate in Rails:

rails generate mailer name_of_email_campaign name(s)_of_email


This will create a mailer model in your ‘app/mailers’ directory, and corresponding views (in text.erb) for the emails attached to that model. Since you’ll be using layouts, I recommend editing the text version first (to get the wording right) before setting up the .html.erb version of your email.


Step 2: Set up MailCatcher
Now that you’ve been messing with your text emails, you probably want to see what they would look like sent, right? No need to deploy and then execute actions to generate the emails (dangerous!) – using a gem called MailCatcher and Rails functionality, you can do this painlessly (and fast!).


MailCatcher makes testing your Rails-based emails super easy. Install the gem (‘gem install mailcatcher’), run it (‘mailcatcher -f’), and then open a browser tab to localhost:1080 to start seeing mailer magic! More info on generating an email to show up here to come. You don’t need to add it to a gemfile, unless others in your team will be using it as well. You may need to make some configuration adjustments, so the emails end up in MailCatcher (check out their documentation for what might apply to your setup).

To send yourself an email for testing, fire up your Rails Console. The format for delivering an email through the console is:


In the case of Wistia emails, we deliver them to a specific account, so the function looks like MailerModel.email_name(account).deliver. The email_name corresponds to the function within your mailer model.

Changes made in views will appear if you run ‘deliver’ again, but any changes to the model will require you to re-start the console to take effect.

With MailCatcher, you can see the HTML and text version quickly, and also run analysis to see what devices won’t work with elements of your layout. It’s super useful.


Step 3: Set up the layout
So now it’s time to get your email looking good. If you’re lucky like me, you’ve got one of the best designers around putting together your table-based layout. If not…my apologies, I haven’t found a good way around that step. If you have (found a way to translate div-based layout into tables) please respond in the comments. Otherwise, I’ll give you some time to get your table-based layout right.

Save it in your normal app/views/layouts directory ‘layout_name.html.erb’. In the spots where you want to add content, I recommend using yields (content_for in your view, see Rails Guides for more). We used yields in three spots: for the image at the top, text content in the body, and link (call-to-action) at the bottom of the email.

All set? Great. In the Mailer model, tell the system to use a layout for HTML emails (and leave the text emails as-is:

mail(to: '', subject: 'something important for you!') do |format|
  format.html { render layout: 'layout.html.erb' }

If you haven’t created an html version of your mailer, you should do so now – same_name_as_text_version.html.erb. But instead of having to include the entire layout, you can just include the content you’d like to pass in. Ah, much better.


Step 4: Commence awesome styling
Ok, so you’re setting up great looking email, and testing it in MailCatcher (use their Fractal functionality as well – so cool to know what won’t work and on which device). What could be better? Well, you had to use inline styles to get things set up, and if you’re anything like me, that drives you just about batshit crazy. Luckily, the Roadie gem is here to rescue you!

Roadie makes using external stylesheets possible with emails. Previously, you had to include ALL styles inline – which was a real pain to look at and maintain. Now, you can use sass to keep track of the styles associated with your emails … wow! Add it to your gemfile (‘gem roadie’) and you’re good to go. Ryan Bates does a good screencast on getting set up with roadie (which is where I first heard about it).

I created a new stylesheet (cleverly called ‘mail.sass’) and moved all my inline styles from the table layout to it.  Then, add a link to your stylesheets at the top of the layout (ie. <link rel=”stylesheet” type=”text/css” href=”mail”> ) and elements in your layout and views will be styled through a stylesheet. So much cleaner.

Extra Notes
One hurdle we had to jump was in relation to images in email layouts. We encountered some real weirdness using ‘image_tag’ with just a link to the image. Instead, we ended up building the full URL using http://#{ ::AppConfig.asset_host }/path_to_image’. Might be helpful if you plan to tackle this project.





Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: