Email Testing

This guide explains how to test email functionality in Plugged.in using Mailtrap for development and staging environments.

Quick Setup with Mailtrap

1

Create Mailtrap Account

Sign up for a free account at Mailtrap.io
2

Get SMTP Credentials

Navigate to Inboxes → Select inbox → SMTP Settings → Choose Nodemailer
3

Configure Environment

EMAIL_SERVER_HOST=sandbox.smtp.mailtrap.io
EMAIL_SERVER_PORT=2525
EMAIL_SERVER_USER=your-mailtrap-username
EMAIL_SERVER_PASSWORD=your-mailtrap-password
EMAIL_FROM=noreply@plugged.in
EMAIL_FROM_NAME=Plugged.in
4

Test Email Delivery

curl -X POST http://localhost:12005/api/auth/test-email \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer your-admin-secret' \
  -d '{"email": "test@example.com"}'

Email Templates

Plugged.in includes responsive HTML email templates for various notifications:

Verification Email

Sent when users register to verify their email address

Password Reset

Sent when users request a password reset

Notifications

Activity alerts and system notifications

Welcome Email

Onboarding email for new users

Development Setup

1. Install Dependencies

Ensure email dependencies are installed:
pnpm install nodemailer @types/nodemailer

2. Configure Mailtrap

  1. Log into Mailtrap Dashboard
  2. Navigate to Inboxes
  3. Click on your inbox
  4. Copy SMTP credentials
  5. Select Nodemailer integration

3. Environment Configuration

Create or update .env.local:
# Mailtrap Settings
EMAIL_SERVER_HOST=sandbox.smtp.mailtrap.io
EMAIL_SERVER_PORT=2525
EMAIL_SERVER_USER=your-username
EMAIL_SERVER_PASSWORD=your-password

# Email Configuration
EMAIL_FROM=noreply@plugged.in
EMAIL_FROM_NAME=Plugged.in
ENABLE_EMAIL_VERIFICATION=true

# Admin Secret for Testing
ADMIN_SECRET=your-secret-key

4. Test Email Functionality

Using Application Forms

  • Password Reset: Visit /forgot-password
  • User Registration: Visit /register
  • Email Verification: Complete registration flow

Using Test Endpoint

# Test email delivery
curl -X POST http://localhost:12005/api/auth/test-email \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer your-admin-secret' \
  -d '{
    "email": "test@example.com",
    "subject": "Test Email",
    "template": "verification"
  }'

Email Template Customization

Template Structure

All email templates follow this structure:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
      /* Responsive styles */
      @media only screen and (max-width: 600px) {
        .container { width: 100% !important; }
      }
    </style>
  </head>
  <body>
    <!-- Header with logo -->
    <div class="header">
      <img src="data:image/png;base64,..." alt="Plugged.in">
    </div>

    <!-- Main content -->
    <div class="content">
      <!-- Dynamic content here -->
    </div>

    <!-- Footer -->
    <div class="footer">
      © 2024 Plugged.in. All rights reserved.
    </div>
  </body>
</html>

Customizing Templates

Edit email templates in lib/email.ts:
// lib/email.ts
export const emailTemplates = {
  verification: (token: string) => ({
    subject: 'Verify your email',
    html: generateTemplate({
      title: 'Email Verification',
      content: `Click below to verify your email`,
      buttonText: 'Verify Email',
      buttonUrl: `${process.env.NEXTAUTH_URL}/verify?token=${token}`
    })
  }),

  passwordReset: (token: string) => ({
    subject: 'Reset your password',
    html: generateTemplate({
      title: 'Password Reset',
      content: `Click below to reset your password`,
      buttonText: 'Reset Password',
      buttonUrl: `${process.env.NEXTAUTH_URL}/reset-password?token=${token}`
    })
  })
};

Logo Customization

Logos are embedded as base64 to ensure display even when images are blocked.
Replace the logo:
// Convert logo to base64
const logoBase64 = fs.readFileSync('logo.png').toString('base64');

// Update in lib/email.ts
const DEFAULT_LOGO_BASE64 = `data:image/png;base64,${logoBase64}`;
Logo Guidelines:
  • Maximum size: 30KB (to avoid email size issues)
  • Recommended dimensions: 200x50px
  • Format: PNG with transparency or JPEG
  • Optimize before converting to base64

Testing Strategies

Unit Testing

// tests/email.test.ts
import { sendEmail } from '@/lib/email';
import { vi, describe, it, expect } from 'vitest';

describe('Email Service', () => {
  it('should send verification email', async () => {
    const mockTransport = {
      sendMail: vi.fn().mockResolvedValue({ messageId: '123' })
    };

    const result = await sendEmail({
      to: 'test@example.com',
      subject: 'Test',
      html: '<p>Test</p>'
    });

    expect(mockTransport.sendMail).toHaveBeenCalled();
    expect(result.messageId).toBe('123');
  });
});

Integration Testing

// tests/email.integration.test.ts
describe('Email Integration', () => {
  it('should deliver to Mailtrap', async () => {
    const response = await fetch('/api/auth/test-email', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${process.env.ADMIN_SECRET}`
      },
      body: JSON.stringify({
        email: 'integration@test.com'
      })
    });

    expect(response.status).toBe(200);

    // Verify in Mailtrap API
    const mailtrapMessages = await checkMailtrap();
    expect(mailtrapMessages).toContainEmail('integration@test.com');
  });
});

Production Email Services

Supported Providers

EMAIL_SERVER_HOST=smtp.sendgrid.net
EMAIL_SERVER_PORT=587
EMAIL_SERVER_USER=apikey
EMAIL_SERVER_PASSWORD=your-sendgrid-api-key

Production Checklist

Email Debugging

Common Issues

Debug Mode

Enable detailed logging:
// lib/email.ts
import { createTransport } from 'nodemailer';

const transporter = createTransport({
  host: process.env.EMAIL_SERVER_HOST,
  port: Number(process.env.EMAIL_SERVER_PORT),
  auth: {
    user: process.env.EMAIL_SERVER_USER,
    pass: process.env.EMAIL_SERVER_PASSWORD,
  },
  debug: true, // Enable debug output
  logger: true // Log to console
});

Testing Tools

Mailtrap

Safe email testing sandbox mailtrap.io

Mail Tester

Spam score analysis mail-tester.com

Litmus

Email client preview testing litmus.com

Email on Acid

Comprehensive email testing emailonacid.com

API Reference

Test Email Endpoint

POST /api/auth/test-email
Authorization: Bearer {admin-secret}

{
  "email": "recipient@example.com",
  "subject": "Custom Subject",
  "template": "verification" | "passwordReset" | "notification"
}

Response:
{
  "success": true,
  "messageId": "abc123",
  "preview": "https://mailtrap.io/inboxes/123/messages/456"
}

Email Service Methods

// Send email
await sendEmail({
  to: string | string[],
  subject: string,
  html: string,
  text?: string,
  attachments?: Array<{
    filename: string,
    content: Buffer
  }>
});

// Send templated email
await sendTemplatedEmail({
  to: string,
  template: 'verification' | 'passwordReset',
  data: {
    token: string,
    userName?: string,
    expiresIn?: string
  }
});

Support

For email testing assistance: