• Phoenix: How to easily preview e-mails in a Bamboo setup

I’ll show how you can easily add a simple controller to preview your e-mails. Bamboo has a sent_email plug to view all emails as they are sent, but if you use HTML layout, or if you’ve an intricate e-mail process it would be much easier to just preview them instead. Fortunately it’s super easy to build a controller to preview your HTML (or plain text) e-mails.


I work with the following setup:

Premailex adds inline style to all elements from the style tags. My mailer looks somewhat like this:

defmodule MyApp.SampleMailer do
  use Bamboo.Phoenix, view: MyApp.MailerView
  import MyApp.Gettext
  alias MyApp.User

  @spec sample_email(Conn.t, %User{}) :: Bamboo.Email.t
  def sample_email(conn, user) do
    |> to({user.name, user.email})
    |> from({"My App", "myapp@example.com"})
    |> subject(gettext("Sample E-mail"))
    |> assign(:conn, conn)
    |> render_email_layout(:sample_email)
    |> premail()

  defp premail(%Bamboo.Email{} = email) do
    |> html_body(Premailex.to_inline_css(email.html_body))
    |> text_body(Premailex.to_text(email.html_body))


We’ll set up development only routes for our preview controller.

defmodule MyApp.Router do
  use MyAppWeb, :router

  # All the other pipelines and routes

  if Mix.env == :dev do
    get "/preview_emails/:type", MyApp.PreviewEmailController, :show


Create a new controller with the filename email_preview_controller.ex, and use the following setup:

defmodule MyApp.PreviewEmailController do
  use MyAppWeb, :controller
  alias MyApp.{User, SampleMailer}

  @spec show(Conn.t, map) :: Conn.t | no_return
  def show(conn, %{"type" => "sample_email"}) do
    user = %User{name: "John Doe",
                 email: "john.doe@example.com"}
    email = BookingMailer.sample_email(conn, user)
    render_email(conn, email)

  defp render_email(conn, email) do
    |> Plug.Conn.put_resp_content_type("text/html")
    |> send_resp(:ok, email.html_body)

Now visit http://localhost:4000/preview_emails/sample_email, and you’ll see the rendered e-mail. If you wish to view the plain text version, you can use email.text_body. Happy coding!

The Author

Dan Schultzer is an active experienced entrepreneur, starting the Being Proactive groups, Dream Conception organization, among other things. You can find him at twitter

Like this post? More from Dan Schultzer

Comments? We would love to hear from you, write us at @dreamconception.