This guide explains how to create HTML email templates using UIx components and send emails from your application.
Email Component System
The saas.common.ui.email
namespace provides a set of UIx components specifically designed for creating consistent HTML emails. These components are inspired by React Email but implemented with ClojureScript and UIx.
Available Components
The email component library includes:
html
- Root wrapper for email contenthead
- Contains head elements like styles and meta tagsbody
- Wrapper for all email contentcontainer
- Centers content with proper width constraintsheading
- A block of heading text (h1-h6)text
- Paragraph text with consistent stylingbutton
- A link styled as a buttonlink
- Styled hyperlinkimg
- Image component optimized for email clientsrow
- Horizontal layout containercolumn
- Column within a rowsection
- Content sectionpreview
- Sets inbox preview texthr
- Horizontal rule dividercode-inline
- Displays code snippets with cross-client support
Creating Email Templates
To create an email template:
Import the necessary components:
(ns your.namespace
(:require
[saas.common.ui.email :as email]
[uix.core :refer [$]]))
Define your email template using UIx components:
(defn welcome-email [{:keys [user-name verification-url]}]
($ email/html
($ email/head)
($ email/preview "Welcome to Ship Clojure! Verify your account")
($ email/body
($ email/container
($ email/heading "Welcome to Ship Clojure!")
($ email/text (str "Hello " user-name ", thank you for signing up!"))
($ email/text "Please verify your account by clicking the button below:")
($ email/button {:href verification-url
:style {:background-color "#5881D8"
:color "#ffffff"
:padding "11px 23px"}}
"Verify Account")))))
Convert the UIx components to HTML:
(def html-email (email/render-email
($ welcome-email
{:user-name "Jane Doe"
:verification-url "https://your-app.com/verify?token=abc123"})))
Styling Components
Components accept style maps similar to React's style prop:
($ email/text {:style {:color "#333333"
:font-size "16px"
:line-height "1.5"}}
"This is styled text")
For margin utilities, use :m
, :mt
, :mr
, :mb
, :ml
, :mx
, or :my
:
($ email/heading {:m 10 :mb 20} "Heading with margins")
Sending Emails
Use the saas.email
namespace to send emails:
(require '[saas.email :as email]
'[saas.common.ui.email :as email-ui])
;; Generate the HTML for your email
(def html-email (email-ui/render-email
($ email-ui/verification-email
{:verification-url "https://your-app.com/verify?token=abc123"
:otp "123456"
:type "onboarding"})))
;; Send the email using the EmailSender protocol
(email/send-email email-sender
{:html html-email
:subject "Verify your account"
:to "user@example.com"
:from "Your App <noreply@your-app.com>"})
The email-sender
is typically injected via the system's dependency injection:
;; In a handler that receives the email-sender as dependency
(defn send-verification-email [{:keys [email-sender]} user verification-code]
(let [html (email-ui/render-email
($ email-ui/verification-email
{:verification-url (str "https://your-app.com/verify/" verification-code)
:otp verification-code
:type "onboarding"}))]
(email/send-email email-sender
{:html html
:subject "Verify your account"
:to (:email user)
:from "Your App <noreply@your-app.com>"})))
Email Configuration
The system uses Resend as the email service provider. Configuration is handled via the :services/email
Integrant component:
;; In your system.edn
{:services/email
{:secrets #ig/ref :services/secrets
:api-url "https://api.resend.com/emails"}}
For local development, a mock email sender is used that logs email contents instead of sending actual emails.
Extracting Plain Text
For better deliverability, include both HTML and plain text versions of your email:
(def html-email (email-ui/render-email your-email-component))
(def text-email (email/extract-text html-email))
(email/send-email email-sender
{:html html-email
:text text-email
:subject "Your Subject"
:to "user@example.com"
:from "Your App <noreply@your-app.com>"})
Example Email Templates
The library includes pre-built templates:
login-code-email
- For sending login verification codes with magic linksverification-email
- For account verification (onboarding, password reset)
Example usage:
(email-ui/render-email
($ email-ui/login-code-email
{:code "123456"
:code-href "https://your-app.com/verify/123456"
:homepage "https://your-app.com"}))
Last updated