The Nuxt Lettermint module provides server-side utilities for sending emails directly from your API routes, server middleware, and Nitro handlers.
Basic usage
Use the sendEmail() function in any server context:
import { sendEmail } from '#imports'
export default defineEventHandler ( async () => {
return await sendEmail ({
from: '[email protected] ' ,
to: '[email protected] ' ,
subject: 'Welcome' ,
html: '<h1>Welcome!</h1>' ,
tags: [ 'welcome' ]
})
} )
The sendEmail() function
The sendEmail() function is a convenience wrapper that handles email sending with all available options:
import { sendEmail , type SendEmailOptions } from '#imports'
const result = await sendEmail ( options )
Returns:
interface EmailResult {
message_id : string
status : string
}
Email options
The sendEmail() function accepts comprehensive email options:
interface SendEmailOptions {
from : string // Sender email address
to : string | string [] // Recipient email address(es)
subject : string // Email subject
text ?: string // Plain text content
html ?: string // HTML content
cc ?: string | string [] // CC recipients
bcc ?: string | string [] // BCC recipients
replyTo ?: string | string [] // Reply-to address(es)
headers ?: Record < string , string > // Custom headers
metadata ?: Record < string , unknown > // Custom metadata
tags ?: string [] // Tags for categorization
attachments ?: Array <{ // File attachments
filename : string
content : string | Buffer
contentType ?: string
}>
}
All options are validated before sending. Either text or html content is required.
Complete example
Here’s a real example from the module’s playground showing a complete server route:
server/api/server-email-demo.ts
import { defineEventHandler } from 'h3'
import { sendEmail } from '#imports'
export default defineEventHandler ( async () => {
try {
const result = await sendEmail ({
from: '[email protected] ' ,
to: '[email protected] ' ,
subject: 'Server-side Email from Nuxt Lettermint' ,
text: 'This email was sent directly from the server using the Lettermint SDK.' ,
html: '<h2>Server-side Email</h2><p>This email was sent directly from the server using the <strong>Lettermint SDK</strong>.</p>' ,
tags: [ 'nuxt' ],
})
return {
success: true ,
message: 'Email sent from server' ,
messageId: result . message_id ,
status: result . status ,
}
}
catch ( error : unknown ) {
console . error ( 'Server email error:' , error )
const err = error as any
let errorMessage = 'Failed to send email from server'
// Extract the actual validation message from Lettermint
if ( err ?. responseBody ?. message ) {
errorMessage = err . responseBody . message
}
else if ( err ?. message ) {
errorMessage = err . message
}
return {
success: false ,
error: errorMessage ,
}
}
} )
Advanced options
The module supports all Lettermint email features. Here’s an example with all available options:
server/api/full-options.ts
import { sendEmail } from '#imports'
export default defineEventHandler ( async () => {
const result = await sendEmail ({
from: '[email protected] ' ,
to: '[email protected] ' ,
cc: '[email protected] ' ,
bcc: '[email protected] ' ,
replyTo: '[email protected] ' ,
subject: 'Test Full Options' ,
text: 'Plain text version' ,
html: '<h1>HTML version</h1>' ,
headers: {
'X-Custom-Header' : 'custom-value' ,
},
metadata: {
userId: '12345' ,
campaign: 'test-campaign' ,
},
tags: [ 'test' , 'full-options' ],
attachments: [
{
filename: 'test.txt' ,
content: 'Test attachment content' ,
},
],
})
return {
success: true ,
result ,
}
} )
Multiple recipients
Send to multiple recipients by passing arrays:
server/api/newsletter.post.ts
Error handling
Always wrap sendEmail() calls in try-catch blocks:
Basic error handling
Detailed error handling
import { sendEmail } from '#imports'
import { createError } from 'h3'
export default defineEventHandler ( async () => {
try {
const result = await sendEmail ({
from: '[email protected] ' ,
to: '[email protected] ' ,
subject: 'Hello' ,
html: '<h1>Hello</h1>'
})
return { success: true , messageId: result . message_id }
}
catch ( error ) {
throw createError ({
statusCode: 500 ,
statusMessage: 'Failed to send email'
})
}
} )
The Lettermint API returns detailed error messages for validation failures. Always extract and return these messages to help debug issues.
Using with request data
Combine with request body parsing for dynamic email sending:
server/api/contact.post.ts
import { defineEventHandler , readBody , createError } from 'h3'
import { sendEmail } from '#imports'
export default defineEventHandler ( async ( event ) => {
const { name , email , message } = await readBody ( event )
// Validate input
if ( ! name || ! email || ! message ) {
throw createError ({
statusCode: 400 ,
statusMessage: 'Missing required fields'
})
}
// Send email
const result = await sendEmail ({
from: '[email protected] ' ,
to: '[email protected] ' ,
replyTo: email ,
subject: `Contact Form: ${ name } ` ,
html: `
<h2>New Contact Form Submission</h2>
<p><strong>From:</strong> ${ name } ( ${ email } )</p>
<p><strong>Message:</strong></p>
<p> ${ message } </p>
` ,
metadata: {
source: 'contact-form' ,
userEmail: email
},
tags: [ 'contact-form' ]
})
return {
success: true ,
messageId: result . message_id
}
} )
File attachments
Add attachments using base64-encoded content or Buffer:
server/api/send-with-attachment.post.ts
import { sendEmail } from '#imports'
import { readFile } from 'fs/promises'
export default defineEventHandler ( async () => {
// Read file from disk
const fileBuffer = await readFile ( './invoice.pdf' )
return await sendEmail ({
from: '[email protected] ' ,
to: '[email protected] ' ,
subject: 'Your Invoice' ,
html: '<h1>Invoice Attached</h1><p>Please find your invoice attached.</p>' ,
attachments: [
{
filename: 'invoice.pdf' ,
content: fileBuffer ,
contentType: 'application/pdf'
}
]
})
} )
For base64-encoded strings, you can pass them directly as the content field without converting to Buffer.
Add custom headers and metadata for tracking and routing:
server/api/campaign.post.ts
import { sendEmail } from '#imports'
export default defineEventHandler ( async () => {
return await sendEmail ({
from: '[email protected] ' ,
to: '[email protected] ' ,
subject: 'Special Offer' ,
html: '<h1>Limited Time Offer</h1>' ,
headers: {
'X-Campaign-ID' : 'spring-2024' ,
'X-Email-Type' : 'promotional'
},
metadata: {
campaignId: 'spring-2024' ,
userId: '67890' ,
segmentId: 'premium-users' ,
timestamp: new Date (). toISOString ()
},
tags: [ 'campaign' , 'promotional' , 'spring-2024' ]
})
} )
How it works
The sendEmail() function:
Retrieves the Lettermint SDK instance configured with your API key
Converts your options into the Lettermint fluent API format
Handles arrays for recipients, CC, BCC, and reply-to fields
Sends the email via the Lettermint API
Returns the message ID and status
Your API key is securely accessed from runtime config and never exposed to the client.
Next steps
Advanced usage Use the fluent API for more control
Custom endpoints Create custom API endpoints with additional logic