DeviseのHTMLメールでBootstrapのようなボタンを使いたい


はじめに

Deviseが送信するメールをBootstrapのボタンを使いたかったので、そのやり方をメモ。結局、BootstrapはGmailではMessage ClippedになったのでFoundation for Emailsにした。

Bootstrap

1. Gem install

使ったpremailer-railsGemは<head>に書いたcssファイルをinline cssに変換してくれる。

Gemfile
# CSS for HTML mail
gem 'premailer-rails'

2. Deviseの設定

今回はDeviseのメールアドレス確認メールでBootstrapを使いたいので、Devise::Mailerapp/views/layouts/mailer.html.erbテンプレートを読み込むようにする。

config/initializers/devise.rb
Devise.setup do |config|
途中省略
  # Configure the class responsible to send e-mails.
  # config.mailer = 'Devise::Mailer'
  config.mailer = 'DeviseMailer'
途中省略
end

# deviseのmailer layoutを設定する
Rails.application.config.to_prepare do
  Devise::Mailer.layout 'mailer'
end

Deviseメールのタイトルを変更する

app/mailers/devise_mailer.rb
class DeviseMailer < Devise::Mailer

  def confirmation_instructions(record, token, opts={})
    logger.info("[LOGGER] DeviseMailer confirmation_instructions started.")
    mail = super
    mail.subject = "HogeHoge " + I18n.t('devise.mailer.confirmation_instructions.subject')
    mail
  end
end

3. mailerテンプレートのカスタマイズ

mailerテンプレートの<head>でBootstrapのCSSを読み込ませる。結果、以下のようになった。

app/views/layouts/mailer.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <!-- 必要なメタタグ -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Bootstrap CDN -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <%#= stylesheet_link_tag "mailer/common", media: "all" %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

4.さっそく試してみる

Deviseでサインアップして、メールアドレス確認のメールにBootstrapのボタンが使えるか試してみた。i18nで多言語化している。class: 'btn btn-primary'を追加している。

app/views/devise/mailer/confirmation_instructions.html.erb
<p><%= t('.greeting', recipient: @email) %></p>
<p><%= t('.instruction') %></p>
<p><%= link_to t('.action'), confirmation_url(@resource, confirmation_token: @token), class: 'btn btn-primary' %></p>


Bootstrapのボタンが出ることを確認できた。ただ、GmailだとMessage Clippedになってしまう。たぶん、Bootstrapはbootstrap.min.cssでもCSSが長すぎるからだろうとは思うが、何か対応策があるかは別途調べる事にする。

Foundation for Emails 2.0

ボタンを使いたいだけであればBootstrapではなくFoundationを試してみる。inkyも試してみたら、Railsのlink_toをどう書けば良いか分からなかったので使わなかった。

1. 変更したファイル

Gemfile
# Foundation for Emails
gem 'premailer-rails'
gem 'foundation_emails'
app/views/layouts/mailer.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width" />

    <%= stylesheet_link_tag "foundation_emails", media: "all" %>
  </head>

  <body>
    <table class="body" data-made-with-foundation>
      <tr>
        <td class="center" align="center" valign="top">
          <center>
            <%= yield %>
          </center>
        </td>
      </tr>
    </table>
  </body>
</html>
app/assets/stylesheets/foundation_emails.scss
@import "foundation-emails";
app/assets/stylesheets/application.css.scss
- *= require_tree .  これをコメントアウトしないとfoundation_emails.scssが読み込まれてしまう
+ * require_tree .
app/views/devise/mailer/confirmation_instructions.html.erb
<p><%= t('.greeting', recipient: @email) %></p>
<p><%= t('.instruction') %></p>
<table class="button">
  <tr>
    <td>
      <table>
        <tr>
          <td>
            <%= link_to t('.action'), confirmation_url(@resource, confirmation_token: @token) %>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>

2. 試してみる

Foundation for EmailsではGmailでもMessage Clippedにならずにボタンが表示できた。

ここまで動けば、あとはメールテンプレートを好きなだけカッコよくすれば良い。

3. scssが読み込まれない

mailer/common.css が無いというエラーが出た場合は参考記事にあるconfig/initializers/assets/assets.rbに以下を追記すれば良い。

config/initializers/assets/assets.rb
Rails.application.config.assets.precompile += %w( mailer/common.css )

参考記事

Deviseのmailerでlayoutを適用する
railsのmailerでcssファイルを使う&画像も入れ
RailsでFoundation for Emails 2.0を使ってレスポンシブなHTMLメールを送る
HTMLメールを作るにあたって知っておきたいこと
Foundation for Emails Read Me
Foundation for Emails 2 Migration Guide
Foundation for Emails Document
How to link scss file with style sheet link tag in Ruby on Rails