---
title: Mailpit Setup
description: Guide for setting up and using Mailpit SMTP server for local email testing during development and E2E tests.
navigation:
  icon: i-lucide-inbox
---

# Email Testing with Mailpit

This guide explains how to test email functionality in E2E tests using Mailpit.

## Overview

Mailpit is a lightweight SMTP server that captures emails during testing without actually sending them. It provides a web interface to view captured emails and an API for automated testing.

## Setup

### 1. Install Mailpit

Mailpit is already installed on your system at:
```
/opt/homebrew/opt/mailpit/bin/mailpit
```

### 2. Automatic Startup

Playwright is configured to automatically start and stop Mailpit when running tests. See `playwright.config.ts`:

```typescript
webServer: [
  {
    command: 'pnpm dev',
    url: 'http://localhost:3000',
    // ... other config
  },
  {
    // Mailpit SMTP server for testing email verification
    command: '/opt/homebrew/opt/mailpit/bin/mailpit',
    url: 'http://localhost:8025', // Mailpit web UI
    reuseExistingServer: true,
    timeout: 10 * 1000,
  },
]
```

### 3. Environment Configuration

When running E2E tests, set these environment variables to enable SMTP mode:

```bash [.env.test]
NUXT_MOCK_EMAIL=false
NUXT_SMTP_HOST=localhost
NUXT_SMTP_PORT=1025
NUXT_SMTP_SECURE=false
```

You can create a `.env.test` file with these values, or set them in your test runner.

## How It Works

::steps
1. **Playwright starts Mailpit** before running tests
2. **App sends emails to Mailpit** instead of real SMTP server
3. **Emails are captured** in Mailpit's inbox
4. **Tests can verify emails** via Mailpit's web UI or API
5. **Mailpit stops** when tests finish
::

## Mailpit Ports

- **SMTP Server**: `localhost:1025` - where your app sends emails
- **Web UI**: `http://localhost:8025` - view captured emails in browser
- **API**: `http://localhost:8025/api/v1` - programmatic access to emails

## Viewing Emails

While tests are running or after they finish, open your browser to:
```
http://localhost:8025
```

You'll see all captured emails with full content, headers, and attachments.

## Using Mailpit in Tests

### Example: Verify Email Verification Flow

```typescript
import { test, expect } from '@playwright/test'

test('user receives verification email', async ({ page, request }) => {
  const testEmail = 'test@example.com'

  // Register user (triggers verification email)
  await page.goto('/auth/register')
  await page.fill('[name="email"]', testEmail)
  await page.fill('[name="password"]', 'Test1234!')
  await page.fill('[name="name"]', 'Test User')
  await page.click('button[type="submit"]')

  // Wait for email to be sent
  await page.waitForTimeout(1000)

  // Query Mailpit API for the email
  const response = await request.get('http://localhost:8025/api/v1/messages')
  const messages = await response.json()

  // Verify email was sent
  expect(messages.messages).toHaveLength(1)
  expect(messages.messages[0].To[0].Address).toBe(testEmail)
  expect(messages.messages[0].Subject).toContain('Verify')

  // Get verification link from email
  const messageId = messages.messages[0].ID
  const message = await request.get(`http://localhost:8025/api/v1/message/${messageId}`)
  const messageData = await message.json()

  // Extract verification URL from email content
  const verificationUrl = extractUrlFromEmail(messageData.Text)

  // Click verification link
  await page.goto(verificationUrl)

  // Verify user is now verified
  await expect(page.getByText(/verified/i)).toBeVisible()
})
```

## Mailpit API Endpoints

- `GET /api/v1/messages` - List all messages
- `GET /api/v1/message/{id}` - Get specific message
- `DELETE /api/v1/messages` - Delete all messages
- `GET /api/v1/message/{id}/source` - Get raw message source

## Troubleshooting

::accordion
:::accordion-item{title="Mailpit doesn't start"}
- Check if port 1025 or 8025 is already in use
- Manually start Mailpit: `/opt/homebrew/opt/mailpit/bin/mailpit`
- Check the console output for errors
:::

:::accordion-item{title="Emails not appearing in Mailpit"}
- Verify SMTP environment variables are set correctly
- Check that `NUXT_MOCK_EMAIL=false` is set
- Look at server logs to confirm emails are being sent via SMTP
- Check Mailpit web UI: http://localhost:8025
:::

:::accordion-item{title="Tests timeout waiting for emails"}
- Increase wait time between sending and checking for email
- Verify Mailpit is actually running on port 8025
- Check network requests in browser devtools
:::
::

## Best Practices

1. **Clean inbox between tests**: Use `DELETE /api/v1/messages` to clear old emails
2. **Use unique emails**: Generate unique email addresses per test to avoid conflicts
3. **Wait for emails**: Add appropriate delays after triggering email sends
4. **Verify email content**: Don't just check if email was sent, verify the content too
5. **Test email links**: Extract and test links from verification/reset emails

## References

- [Mailpit Documentation](https://github.com/axllent/mailpit)
- [Playwright Web Server Configuration](https://playwright.dev/docs/test-webserver)
- [Resend SMTP Configuration](https://resend.com/docs)
