CerberusEmail
Cross-client-tested responsive email components for Phoenix, built on the Cerberus email framework.
Table-based layout with MSO/Outlook conditional comments and mobile stacking via media queries. Branding (product name, footer, colors, font) is passed as attrs — not hardcoded — so the same components work for any product.
Installation
def deps do
[
{:cerberus_email, "~> 0.1"}
]
end
Usage
<.email_layout brand_name="Acme" footer_text="Acme Inc" preview_text="Welcome!">
<.email_one_column_text_button
heading="Welcome to Acme"
button_text="Get Started"
button_url="https://acme.example.com/start"
>
<p style="margin: 0 0 10px;">Click below to get started.</p>
</.email_one_column_text_button>
</.email_layout>
Render to an HTML string for use with a mailer:
import CerberusEmail.Components
import Phoenix.Component
html =
~H"""
<.email_layout brand_name="Acme" footer_text="Acme Inc" preview_text="Welcome!">
<.email_one_column_text>
<p style="margin: 0;">Hello!</p>
</.email_one_column_text>
</.email_layout>
"""
|> Phoenix.HTML.Safe.to_iodata()
|> IO.iodata_to_binary()
Components
| Component | Description |
|---|---|
email_layout |
Outer HTML shell with <head>, MSO comments, preview text, header, footer |
email_content_block |
White-background content wrapper |
email_text_row |
Text row with standard padding and typography |
email_button_row |
Centered primary action button |
email_secondary_button_row |
Outlined secondary button |
email_one_column_text_button |
Combined heading + text + button block |
email_one_column_text |
Text-only block |
email_spacer |
Vertical spacer |
Branding attrs (email_layout)
| Attr | Default | Description |
|---|---|---|
brand_name |
"App" |
Shown in header and footer |
footer_text |
falls back to brand_name |
Footer line |
primary_color |
"#3b82f6" |
Button/accent color |
font_family |
"'Inter', sans-serif" |
Font stack |
preview_text |
nil |
Preview text shown in email clients |
show_header |
true |
Whether to render the brand name header |
License
MIT