Welcome to the Jose Madrid Salsa developer docs — explore features, APIs, and deployment guides.
Jose Madrid SalsaJMS Docs

Email Templates

React Email templates for transactional and marketing emails

Email Templates

Jose Madrid Salsa uses React Email to build transactional email templates as React components. Templates live in the emails/ directory and are rendered to HTML at send time.

Directory Structure

emails/
  components/
    Button.tsx          # Reusable CTA button
    EmailFooter.tsx     # Standard footer with unsubscribe link
    EmailHeader.tsx     # Brand header with logo/image
    EmailLayout.tsx     # Base layout wrapper
    OrderItemsTable.tsx # Order line items table
  contact-form.tsx          # Contact form submission notification
  delivery-confirmation.tsx # Delivery confirmation email
  order-confirmation.tsx    # Order confirmation email
  shipping-notification.tsx # Shipping notification email
  styles.ts                 # Shared style constants

Template Components

EmailLayout

The base layout wraps all emails with consistent structure:

emails/components/EmailLayout.tsx
<EmailLayout previewText="Order #123 confirmed">
  {/* Email content */}
</EmailLayout>

OrderConfirmationEmail

The order confirmation template accepts typed props:

emails/order-confirmation.tsx
interface OrderConfirmationEmailProps {
  name?: string
  orderNumber: string
  orderDate: string
  orderTotal: string
  items: OrderItem[]
  shippingAddress: string
  trackingLink?: string
  unsubscribeUrl?: string
}

export const OrderConfirmationEmail = ({
  name = 'there',
  orderNumber,
  orderDate,
  orderTotal,
  items = [],
  shippingAddress,
  trackingLink,
  unsubscribeUrl = '#',
}: OrderConfirmationEmailProps) => {
  return (
    <EmailLayout previewText={`Order #${orderNumber} confirmed`}>
      <EmailHeader headerImage="order-confirmed.png" headerAlt="Order Confirmed" />
      {/* Order details, items table, total, tracking link */}
      <EmailFooter unsubscribeUrl={unsubscribeUrl} />
    </EmailLayout>
  )
}

Shared Components

ComponentPurpose
ButtonCTA button with variant (primary/secondary) and size props
EmailHeaderBranded header with configurable image
EmailFooterFooter with unsubscribe link and brand info
OrderItemsTableRenders line items with name, quantity, and price

Rendering

Templates are rendered to HTML using @react-email/render:

lib/email/client.ts
import { render } from '@react-email/render'

const html = await render(react) // react = React Email component

@react-email/render is listed in serverExternalPackages in next.config.mjs to ensure it works correctly in server components.

Database Templates

In addition to React Email templates, the application stores HTML email templates in the database (EmailTemplate model) for campaign emails. These support variable substitution:

lib/email/sender.ts
export function substituteVariables(
  template: string,
  variables: Record<string, any>
): string {
  let result = template
  Object.keys(variables).forEach((key) => {
    const regex = new RegExp(`{{\\s*${key}\\s*}}`, 'g')
    result = result.replace(regex, String(variables[key] ?? ''))
  })
  return result
}

Variables use {{variableName}} syntax (e.g., {{name}}, {{orderNumber}}).

Template Categories

Database templates are categorized:

enum EmailTemplateCategory {
  TRANSACTIONAL
  MARKETING
  NOTIFICATION
  SYSTEM
}

Styling

Email styles use inline CSS objects (React Email convention):

emails/styles.ts
// Shared styles imported by all templates
export const bodyContent = { ... }

Individual templates define additional styles as const objects with proper TypeScript typing:

const heading = {
  margin: '0 0 24px',
  fontSize: '24px',
  fontWeight: '700' as const,
  color: '#dc2626',  // Jose Madrid brand red
  fontFamily: 'Arial, sans-serif',
}

Brand Colors

ColorHexUsage
Brand Red#dc2626Headings, CTA buttons, totals
Dark Text#1f2937Body text
Muted Text#64748bSecondary text, labels
Link Blue#3b82f6Hyperlinks
Background#f8fafcCard backgrounds

How is this guide?

Edit on GitHub

Last updated on

On this page