> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lettr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Test Emails

> Send test emails through Lettr's full delivery pipeline to check rendering and merge tags without affecting analytics or engagement

Before sending emails to real recipients, you should verify that your templates render correctly, merge tags resolve to the expected values, and links point to the right destinations. Test emails let you send a real email through the full delivery pipeline — including template rendering and merge tag substitution — to your own inbox, without affecting your analytics or engagement metrics.

## Send a Test Email

You can send test emails from the Lettr dashboard or via the regular send API. Test emails use the same rendering pipeline as production sends, so what you see in your inbox is exactly what your recipients will receive:

```javascript theme={null}
await lettr.emails.send({
  from: 'you@yourdomain.com',
  to: ['developer@example.com'],
  subject: 'Welcome to Acme',
  template_slug: 'welcome-email',
  substitution_data: {
    name: 'Test User',
    company: 'Acme Inc'
  }
});
```

## Test with Custom HTML

Test custom HTML content without using a template:

```javascript theme={null}
await lettr.emails.send({
  from: 'you@yourdomain.com',
  to: ['developer@example.com'],
  subject: 'Test Email',
  html: '<h1>Testing</h1><p>This is a test email with {{name}}.</p>',
  substitution_data: {
    name: 'Preview Name'
  }
});
```

## Multiple Test Recipients

When reviewing a template as a team, send the test to multiple recipients at once — developers, designers, and QA engineers can each verify the email in their preferred email client:

```javascript theme={null}
await lettr.emails.send({
  from: 'you@yourdomain.com',
  to: [
    'developer@example.com',
    'designer@example.com',
    'qa@example.com'
  ],
  subject: 'Order Confirmation Test',
  template_slug: 'order-confirmation',
  substitution_data: {
    order_id: 'TEST-12345',
    customer_name: 'Test Customer',
    total: '$99.99'
  }
});
```

## Test Different Variables

Templates often contain conditional blocks that display different content based on the data provided. Test with both minimal and complete data sets to verify that conditionals, loops, and default values all render as expected:

```javascript theme={null}
// Test with minimal data
await lettr.emails.send({
  from: 'you@yourdomain.com',
  to: ['developer@example.com'],
  subject: 'Welcome',
  template_slug: 'welcome-email',
  substitution_data: {
    name: 'User'
  }
});

// Test with full data
await lettr.emails.send({
  from: 'you@yourdomain.com',
  to: ['developer@example.com'],
  subject: 'Welcome',
  template_slug: 'welcome-email',
  substitution_data: {
    name: 'John Smith',
    company: 'Acme Corporation',
    role: 'Administrator',
    features: ['Dashboard', 'Reports', 'API Access']
  }
});
```

## Test Email Characteristics

Test emails behave differently from production sends in a few important ways:

| Feature     | Behavior                                 |
| ----------- | ---------------------------------------- |
| Tracking    | Disabled by default                      |
| Analytics   | Not counted in statistics                |
| Webhooks    | Events still fire (for testing webhooks) |
| Rate limits | Subject to normal rate limits            |

## Testing in the Dashboard

The Lettr dashboard provides a visual test email feature:

1. Open your template in the editor
2. Click "Send Test Email"
3. Enter test recipient addresses
4. Optionally provide test variable data
5. Click "Send"

<Tip>
  Use the dashboard preview to see how your email renders before sending test emails.
</Tip>

## Best Practices

<AccordionGroup>
  <Accordion title="Test Across Email Clients">
    Rendering varies significantly between clients. Send test emails to Gmail (web and mobile), Outlook (Windows uses Word's rendering engine, which handles CSS differently), Apple Mail, and at least one mobile client. Check layout, images, fonts, and button styling on each.
  </Accordion>

  <Accordion title="Test Edge Cases">
    Templates may break with unexpected data. Test with missing optional variables (to verify defaults), very long strings (to check truncation and wrapping), special characters and Unicode (to catch encoding issues), and empty arrays (to verify loop blocks render cleanly when there's no data).
  </Accordion>

  <Accordion title="Test Links">
    Click every link in the test email to verify it resolves to the correct destination. Pay particular attention to merge tag links (e.g., `{{tracking_url}}`), unsubscribe links, and tracking-wrapped URLs. Broken links in transactional emails erode user trust.
  </Accordion>

  <Accordion title="Test Plain Text Version">
    If you include a plain text version, review it for readability. Confirm that links are displayed as full URLs, formatting is clear without HTML markup, and the content matches the HTML version. Some recipients and accessibility tools display only the text version.
  </Accordion>

  <Accordion title="Use Realistic Data">
    Synthetic data like "Test User" and "\$0.00" can mask formatting issues. Test with data that resembles production values — real name lengths, actual currency amounts, realistic order item counts — to catch problems like truncated fields, misaligned columns, or overflowing containers.
  </Accordion>
</AccordionGroup>

## Staging Environment

For automated integration tests or CI pipelines, redirect all emails to a staging inbox rather than sending to real recipients. This lets your test suite exercise the full send path without risk of reaching customers:

```javascript theme={null}
const isProduction = process.env.NODE_ENV === 'production';

await lettr.emails.send({
  from: 'you@example.com',
  to: isProduction
    ? [realRecipient]
    : ['staging-inbox@example.com'],
  subject: 'Order Confirmation',
  template_slug: 'order-confirmation',
  substitution_data: orderData
});
```
