Ruby on Rails - send Emails with style

Have you ever had to send emails from your Rails application?

Probably your answer will be yes. Most of us dealt already at some point with the pain of sending HTML formatted emails using Ruby on Rails. Some CSS is already recognized, but usually we end up writing the views with the inline CSS (ouch!), resulting in huge and almost unreadable files.

One does not simply mess with CSS

What are the available options to solve this problem? After some research I found a few Ruby gems that were released recently and that can help you accomplish this task: Roadie, Premailer-rails, actionmailer_inline_css and inline_styles_mailer

Next I’ll go through each one and give you a resumed explanation of how to setup and use those gems.

Roadie

Roadie automatically gets all your CSS inlined paying special attention to selectors. Also, it rewrites all relative into absolute paths and respects any inline styles you may have. Additionally, it adds the HTML skeleton and is able to use partials.

Usage - add the following to your Gemfile:

gem 'roadie', '~> 3.4' 

Creating a new instance of a Roadie document

Transform full documents with the #transform method.

document = Roadie::Document.new "<html><body></body></html>"
document.add_css "body { color: green; }"
document.transform
# => "<html><body style=\"color:green;\"></body></html>"

Transform partial documents with #transform_partial

document.add_css "div { color: green; }"
document.transform_partial
# => "<div style=\"color:green;\">Hello world!</div>"

There are several options that you can use to configure your document instance (for more info check their homepage):

url_options - Dictates how absolute URLs should be built;
keep_uninlinable_css - Set to false to skip CSS that cannot be inlined;
merge_media_queries - Set to false to not group media queries. Some users might prefer to not group rules within media queries because it will result in rules getting reordered;
asset_providers - A list of asset providers that are invoked when CSS files are referenced;
external_asset_providers - A list of asset providers that are invoked when absolute CSS URLs are referenced;
before_transformation - A callback run before transformation starts;
after_transformation - A callback run after transformation is completed.

My thoughts on Roadie

Roadie is extremely complete and with several useful options, however in my opinion it might be a bit too complex, depending on what you need or want. If you need to use assets from a CDN or use cache this gem will be the best option.

Premailer-rails

Just like Roadie, Premailer-rails does an excellent job converting your CSS to inline styles. You don’t need Rails to use as it plays well with Sinatra.
Premailer-rails is automatically used by actionmailer once you add it to your Gemfile. Premailer-rails uses Premailer.

Usage - add the following to your Gemfile:

gem 'premailer-rails' 

Premailer can be configured with the following options, you can do this on the initializer (config/initializers/premailer_rails.rb):

Premailer::Rails.config.merge!(preserve_styles: true, remove_ids: true) 

Premailer default configs

{
  input_encoding: 'UTF-8',
  generate_text_part: true,
  strategies: [:filesystem, :asset_pipeline, :network]
}

To prevent Premailer from generating a text part from HTML just set generate_text_part to false.

If necessary you can disable Premailer for a certain email, setting skip_premailer to true, just like this:


class UserMailer < ActionMailer::Base
  def welcome_email(user)
    mail to: user.email,
         subject: 'Welcome to My Awesome Site',
         skip_premailer: true
  end
end

My thoughts on Premailer-Rails

Premailer is very simple to use and configure, if you just want to send styled emails without special configurations this gem is a very good option.

Actionmailer Inline CSS

This gem is similar to Premailer-rails (it’s also based in Premailer). You just need to add it to your Gemfile and you’re good to go.

Usage - add the following to your Gemfile:

gem 'actionmailer_inlines_css' 

With this gem you can also add a custom CSS file that will be inlined by premailer. You can accomplish this by adding to you email template:

<%= stylesheet_link_tag '/stylesheets/mailers/build_mailer' %> 

My thoughts on Actionmailer Inline CSS

Actionmailer Inline CSS is the easier solution until now. You just need to add it to Gemfile and you’re ready to send styled emails. If you don’t need any special configurations this gem is a must for you.

Inline Styles Mailer

Just like Premailer-rails and Actionmailer Inline CSS this gem uses Premailer and works out of the box.

Usage - add the following to your Gemfile:

gem 'inline_styles_mailer' 

And then just add to the desired mailers the include line for InlineStylesMailer:


class FooMailer < ActionMailer::Base
  include InlineStylesMailer
  def foo(email)
    mail(:to => email, :subject => "Foo foo!")
  end
end 

If you have a CSS file app/assets/stylesheets/foo_mailer* (where the asterisk can be .css, .css.scss or .css.sass) then it will get automatically applied to the mail using the inline_styles gem.

If you want you can use a different CSS file

class FooMailer < ActionMailer::Base
  include InlineStylesMailer
  use_stylesheet '_bar.css.sass'
  ...
end

You can even use more than one CSS file

class FooMailer < ActionMailer::Base
  include InlineStylesMailer
  stylesheet_path 'public/stylesheets'
  ...
end

My thoughts on Inline Styles Mailer

Inline Styles Mailer is also a nice solution, it’s very similar to Premailer-rails and Actionmailer Inline CSS. Easy to configure and able to deal with multiple CSS files. In my opinion it is also a good choice depending on what you need.

Wrapping up

Depending on what your needs are, you can choose between 3 gems based on premailer (Premailer-rails, Actionmailer Inline CSS and Inline Styles Mailer) or Roadie.

Roadie has advanced configuration options (if you need special configurations in order to use CDN or to use cache) that may become useful but if your requirements are not so high you may choose between the other three gems, all based in premailer and with a very similar usage.

For more information about the options presented here, don’t forget to check each gem's link.

At Imaginary Cloud, we simplify complex systems, delivering interfaces that users love. If you’ve enjoyed this article, you will certainly enjoy our newsletter, which may be subscribed below. Take this chance to also check our latest work and, if there is any project that you think we can help with, feel free to reach us. We look forward to hearing from you!