Skip to content

Email Templates System

Complete email template system with multiple providers, responsive design, and admin preview interface.

Preview

Contact Form Component Preview

Overview

The email template system provides a comprehensive solution for managing all transactional emails in your SaaS application. It includes 9 different template types, an integrated preview system, and flexible API endpoints.

Features

  • 9 Professional Templates - Welcome, Newsletter, Purchase, Password Reset, Notifications, Subscriptions, OTP
  • Real-time Preview - Admin interface to test and preview all templates
  • Responsive Design - Mobile and desktop optimized with dark mode support
  • Multi-provider Support - Resend, SendGrid, SMTP support
  • Flexible API - Generation and sending via API endpoints
  • Dynamic Variables - Templating system with custom variables
  • Integrated Testing - Send test emails from admin interface

Available Template Types

1. Welcome Email

Welcome email for new users

typescript
const { generateWelcomeEmail } = useEmailTemplate()

const html = generateWelcomeEmail({
  subject: 'Welcome to Clawplate!',
  greeting: 'Hi John!',
  mainMessage: 'Thank you for joining us.',
  buttonText: 'Get Started',
  buttonUrl: '/dashboard'
})

2. Newsletter

Regular newsletters and updates

typescript
const html = generateNewsletterEmail({
  subject: 'Your Weekly Newsletter',
  title: 'This Week\'s Updates',
  newsletterContent: 'Here are the latest news...',
  mainMessage: 'Discover our latest features.'
})

3. Purchase Confirmation

Order confirmations and invoices

typescript
const html = generatePurchaseEmail({
  subject: 'Order Confirmed',
  orderId: '#12345',
  orderDate: '2025-01-15',
  orderTotal: '$29.99',
  buttonText: 'View Order',
  buttonUrl: '/orders/12345'
})

4. Password Reset

Password reset instructions

typescript
const html = generatePasswordResetEmail({
  subject: 'Reset Your Password',
  greeting: 'Hello!',
  mainMessage: 'Click the button below to reset your password.',
  buttonUrl: '/reset-password?token=abc123'
})

5. Notifications

System notifications and alerts

typescript
const html = generateNotificationEmail({
  subject: 'Important Notification',
  notificationTitle: 'Security Update',
  notificationMessage: 'Your account has been updated.',
  mainMessage: 'Action required from you.'
})

6. Subscription Welcome

Premium subscription welcome

typescript
const html = generateSubscriptionWelcomeEmail({
  subject: 'Welcome to Pro Plan!',
  planName: 'Pro Plan',
  billingInterval: 'monthly',
  nextBillingDate: '2025-02-15',
  buttonUrl: '/dashboard'
})

7. Subscription Canceled

Subscription cancellation confirmation

typescript
const html = generateSubscriptionCanceledEmail({
  subject: 'Subscription Canceled',
  planName: 'Pro Plan',
  accessUntil: '2025-02-15',
  buttonUrl: '/dashboard/billing'
})

8. Payment Failed

Payment failure notifications

typescript
const html = generatePaymentFailedEmail({
  subject: 'Payment Failed - Action Required',
  planName: 'Pro Plan',
  retryDate: '2025-01-18',
  invoiceUrl: '/billing/invoice/123'
})

9. OTP Code

One-time password verification

typescript
// Integrated Supabase template
// Used automatically by Supabase Auth
// Code: \{\{ .Token \}\}

Configuration and Usage

Installation

bash
# Dependencies are already installed in the boilerplate
npm install resend  # If using Resend

Environment Variables Configuration

env
# .env
RESEND_API_KEY=your_resend_api_key
# or
SENDGRID_API_KEY=your_sendgrid_api_key
# or configure your SMTP

Basic Usage

typescript
// In your component or API
import { useEmailTemplate } from '~/composables/useEmailTemplate'
import { sendTransactionalEmail } from '~/server/utils/email'

const { generateWelcomeEmail } = useEmailTemplate()

// Generate HTML
const emailHtml = generateWelcomeEmail({
  subject: 'Welcome!',
  greeting: 'Hi John!',
  mainMessage: 'Thank you for joining us.'
})

// Send email
const result = await sendTransactionalEmail(
  'user@example.com',
  'Welcome!',
  emailHtml
)

Admin Preview Interface

Access /admin/email-preview to:

  • Preview all templates in real-time
  • Customize variables (name, message, price, etc.)
  • Test emails by sending to your address
  • Copy generated HTML
  • Mobile/desktop preview
  • Integrated documentation

Interface Features

  1. Template Selector - Choose from 9 types
  2. Dynamic Configuration - Modify variables in real-time
  3. Responsive Preview - Test mobile and desktop
  4. Test Sending - Receive email in your inbox
  5. HTML Export - Copy generated code

API Endpoints

POST /api/email/preview

Generates HTML preview of a template

typescript
// Request
{
  "type": "welcome",
  "data": {
    "subject": "Bienvenue !",
    "recipientName": "John Doe",
    "mainMessage": "Merci de nous avoir rejoint."
  }
}

// Response
{
  "success": true,
  "html": "<html>...</html>",
  "type": "welcome",
  "timestamp": "2025-01-15T10:00:00Z"
}

POST /api/email/send-test

Sends a test email

typescript
// Request
{
  "to": "test@example.com",
  "type": "welcome",
  "data": {
    "subject": "Test Welcome",
    "recipientName": "Test User"
  }
}

// Response
{
  "success": true,
  "messageId": "msg_123",
  "recipient": "test@example.com",
  "type": "welcome"
}

Available Template Variables

Common Variables (all templates)

typescript
{
  subject: string           // Email subject
  title: string            // Main title
  greeting: string         // Greeting
  mainMessage: string      // Main message
  buttonText?: string      // Button text
  buttonUrl?: string       // Button URL
  additionalMessage?: string // Additional message
}

Specific Variables

Purchase Template

typescript
{
  orderId: string          // Order ID
  orderDate: string        // Order date
  orderTotal: string       // Order total
  amount: string           // Amount
  currency: string         // Currency
}

Subscription Templates

typescript
{
  planName: string         // Plan name
  billingInterval: string  // Billing interval
  nextBillingDate: string  // Next billing date
  accessUntil: string      // Access until
}

Notification Template

typescript
{
  notificationTitle: string    // Notification title
  notificationMessage: string  // Notification message
}

Configuration Variables

typescript
{
  supportEmail: string     // Support email
  websiteUrl: string       // Website URL
  privacyUrl: string       // Privacy policy URL
  termsUrl: string         // Terms of service URL
  unsubscribeUrl: string   // Unsubscribe URL
  twitterUrl: string       // Twitter URL
  linkedinUrl: string      // LinkedIn URL
  githubUrl: string        // GitHub URL
  currentYear: number      // Current year
}

Template Customization

Modify Main HTML Template

Edit templates/email-template.html to:

  • Change colors and styles
  • Modify structure
  • Add new conditional blocks
  • Customize footer

Create New Template Type

  1. Add type in composable:
typescript
// composables/useEmailTemplate.ts
const generateCustomEmail = (data: EmailTemplateData): string => {
  const template = getTemplate()
  const emailData: EmailTemplateData = {
    ...defaultConfig,
    ...data,
    isCustom: true, // New flag
  } as EmailTemplateData
  return compileTemplate(template, emailData)
}
  1. Add condition in HTML template:
html
<!-- templates/email-template.html -->
\{\{#if isCustom\}\}
<div class="info-box">
    <h3>\{\{customTitle\}\}</h3>
    <p>\{\{customMessage\}\}</p>
</div>
\{\{/if\}\}
  1. Add to preview API:
typescript
// server/api/email/preview.post.ts
case 'custom':
  html = generateCustomEmail(data)
  break

Multi-Provider Configuration

typescript
// .env
RESEND_API_KEY=re_your_api_key

// server/utils/email.ts - Already configured

SendGrid

typescript
// .env
SENDGRID_API_KEY=SG.your_api_key

// server/utils/email.ts
if (process.env.SENDGRID_API_KEY) {
  const sgMail = require('@sendgrid/mail')
  sgMail.setApiKey(process.env.SENDGRID_API_KEY)
  
  const result = await sgMail.send({
    to: options.to,
    from: options.from,
    subject: options.subject,
    html: options.html
  })
}

SMTP Custom

typescript
// server/utils/email.ts
import nodemailer from 'nodemailer'

const transporter = nodemailer.createTransporter({
  host: process.env.SMTP_HOST,
  port: process.env.SMTP_PORT,
  secure: true,
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS
  }
})

Best Practices

1. Error Handling

typescript
try {
  const result = await sendTransactionalEmail(email, subject, html)
  if (!result.success) {
    console.error('Email failed:', result.error)
  }
} catch (error) {
  console.error('Email error:', error)
}

2. Environment Variables

typescript
// Always verify API keys
if (!process.env.RESEND_API_KEY) {
  throw new Error('RESEND_API_KEY is required')
}

3. Conditional Templates

typescript
// Use flags for dynamic templates
const emailData = {
  ...baseData,
  isWelcome: userType === 'new',
  isPurchase: orderExists,
  hasButton: actionRequired
}

4. Automated Testing

typescript
// test/email.test.ts
describe('Email Templates', () => {
  test('generates welcome email', () => {
    const html = generateWelcomeEmail({ subject: 'Test' })
    expect(html).toContain('Welcome')
  })
})

Supabase Auth Integration

OTP Email Configuration

  1. In Supabase Dashboard:

    • Go to Authentication → Email Templates
    • Select "Confirm signup"
    • Copy content from templates/email-otp-supabase.html
  2. Available Supabase Variables:

    • \{\{ .Token \}\} - OTP Code
    • \{\{ .SiteURL \}\} - Your site URL
    • \{\{ .Email \}\} - User email

Monitoring and Analytics

Email Logs

typescript
// server/utils/email.ts
console.log('Email sent:', {
  to: options.to,
  subject: options.subject,
  messageId: result.messageId,
  timestamp: new Date().toISOString()
})
  • Delivery rate
  • Open rate
  • Click rate
  • Send errors

Troubleshooting

Common Issues

  1. Emails not received:

    • Check spam/junk folders
    • Confirm API key
    • Check server logs
  2. Broken templates:

    • Validate HTML
    • Check missing variables
    • Test with preview interface
  3. Variables not replaced:

    • Check \{\{variable\}\} syntax
    • Confirm variable exists in data

Debug Mode

typescript
// Enable in development
if (process.env.NODE_ENV === 'development') {
  console.log('Email HTML:', html)
  console.log('Email data:', emailData)
}

Conclusion

The email template system provides:

  • Time Saving - Ready-to-use templates
  • Professional Design - Modern and responsive design
  • Flexibility - Easy customization
  • Reliability - Multi-provider with fallbacks
  • Easy Testing - Integrated preview interface

To get started: Visit /admin/email-preview and explore all available templates!

The email system handles all transactional communications for your SaaS, from welcome messages to subscription notifications, ensuring professional and consistent communication with your users.

Built with love by mhdevfr