🚀
ShipClojure
  • README
  • Development
    • Getting Started
    • REPL Workflow
    • AI Development with ShipClojure
    • Getting Updates
    • Formatting code
    • ShipClojure Guiding Principles
  • Backend
    • Migrations
    • Secrets
    • Routing
    • ShipClojure Blog
    • Email
  • Frontend
    • UIx + re-frame
    • HTTP Requests with Re-frame
    • Frontend Navigation with Re-frame
    • Toast Notifications
    • Icons
  • Server Side Rendering
    • Static/Landing pages
  • Auth
    • How Auth works
    • Oauth2 providers
  • Deployment
    • Deployment
  • Decisions
    • 001 - Cookie Sessions
    • 002 - Single Page Application Architecture
    • 003 - Re-frame instead of Refx
    • 003 - Move from cookie sessions to JWT Access + refresh tokens
Powered by GitBook
On this page
  • Email Component System
  • Available Components
  • Creating Email Templates
  • Styling Components
  • Sending Emails
  • Email Configuration
  • Extracting Plain Text
  • Example Email Templates
  1. Backend

Email

PreviousShipClojure BlogNextUIx + re-frame

Last updated 1 month ago

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 but implemented with ClojureScript and UIx.

Available Components

The email component library includes:

  • html - Root wrapper for email content

  • head - Contains head elements like styles and meta tags

  • body - Wrapper for all email content

  • container - Centers content with proper width constraints

  • heading - A block of heading text (h1-h6)

  • text - Paragraph text with consistent styling

  • button - A link styled as a button

  • link - Styled hyperlink

  • img - Image component optimized for email clients

  • row - Horizontal layout container

  • column - Column within a row

  • section - Content section

  • preview - Sets inbox preview text

  • hr - Horizontal rule divider

  • code-inline - Displays code snippets with cross-client support

Creating Email Templates

To create an email template:

  1. Import the necessary components:

(ns your.namespace
  (:require
   [saas.common.ui.email :as email]
   [uix.core :refer [$]]))
  1. 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")))))
  1. 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

;; 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:

  1. login-code-email - For sending login verification codes with magic links

  2. verification-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"}))

The system uses as the email service provider. Configuration is handled via the :services/email Integrant component:

React Email
Resend