The Nuxt Lettermint module provides access to the Lettermint SDK’s fluent API for advanced use cases and more control over email composition.
Fluent API overview
The fluent API allows you to chain methods to build your email step by step. This is useful when you need more control over the email construction or want to conditionally add properties.
Server-side fluent API
Access the Lettermint SDK directly on the server using useLettermint():
server/api/advanced-send.ts
import { useLettermint } from '#imports'
export default defineEventHandler ( async () => {
const lettermint = useLettermint ()
const result = await lettermint . email
. from ( '[email protected] ' )
. to ( '[email protected] ' )
. subject ( 'Test SDK Email' )
. html ( '<h1>Hello from Lettermint SDK</h1>' )
. tag ( 'sdk-test' )
. send ()
return {
success: true ,
result ,
}
} )
The server-side useLettermint() returns the Lettermint SDK instance, not the client composable. These are two different functions with the same name but different contexts.
Available fluent methods
The Lettermint SDK provides the following chainable methods:
Method Description Example .from(email)Set sender email .from('[email protected] ').to(email)Add recipient .to('[email protected] ').cc(email)Add CC recipient .cc('[email protected] ').bcc(email)Add BCC recipient .bcc('[email protected] ').replyTo(email)Set reply-to address .replyTo('[email protected] ').subject(text)Set email subject .subject('Welcome!').text(content)Set plain text content .text('Hello world').html(content)Set HTML content .html('<h1>Hello</h1>').tag(name)Add a tag .tag('welcome').headers(obj)Set custom headers .headers({ 'X-Custom': 'value' }).metadata(obj)Set metadata .metadata({ userId: '123' }).attach(filename, content)Add attachment .attach('file.pdf', base64Data).send()Send the email .send()
All methods except .send() return the email builder, allowing you to chain multiple calls.
Conditional email building
The fluent API is perfect for building emails conditionally:
server/api/conditional-email.ts
import { useLettermint } from '#imports'
export default defineEventHandler ( async ( event ) => {
const lettermint = useLettermint ()
const { user , includeCopy , urgentFlag } = await readBody ( event )
// Start building the email
let email = lettermint . email
. from ( '[email protected] ' )
. to ( user . email )
. subject ( 'Your Report' )
. html ( '<h1>Report Ready</h1>' )
// Conditionally add CC
if ( includeCopy && user . managerEmail ) {
email = email . cc ( user . managerEmail )
}
// Conditionally add tags
if ( urgentFlag ) {
email = email . tag ( 'urgent' )
}
email = email . tag ( 'report' )
// Conditionally add metadata
if ( user . id ) {
email = email . metadata ({
userId: user . id ,
reportType: 'monthly'
})
}
return await email . send ()
} )
Multiple recipients with fluent API
You can call recipient methods multiple times to add multiple recipients:
server/api/multi-recipient.ts
import { useLettermint } from '#imports'
export default defineEventHandler ( async () => {
const lettermint = useLettermint ()
const recipients = [ '[email protected] ' , '[email protected] ' , '[email protected] ' ]
// Start with base email
let email = lettermint . email
. from ( '[email protected] ' )
. subject ( 'Team Update' )
. html ( '<h1>Important Update</h1>' )
// Add all recipients
recipients . forEach ( recipient => {
email = email . to ( recipient )
})
return await email . send ()
} )
Add multiple tags by chaining .tag() calls:
import { useLettermint } from '#imports'
export default defineEventHandler ( async () => {
const lettermint = useLettermint ()
return await lettermint . email
. from ( '[email protected] ' )
. to ( '[email protected] ' )
. subject ( 'Spring Sale' )
. html ( '<h1>50% Off Everything</h1>' )
. tag ( 'campaign' )
. tag ( 'promotional' )
. tag ( 'spring-2024' )
. tag ( 'sale' )
. send ()
} )
Working with attachments
The .attach() method accepts a filename and base64-encoded content:
server/api/send-attachment.ts
import { useLettermint } from '#imports'
import { readFile } from 'fs/promises'
export default defineEventHandler ( async () => {
const lettermint = useLettermint ()
// Read and encode file
const fileBuffer = await readFile ( './report.pdf' )
const base64Content = fileBuffer . toString ( 'base64' )
return await lettermint . email
. from ( '[email protected] ' )
. to ( '[email protected] ' )
. subject ( 'Monthly Report' )
. html ( '<h1>Monthly Report Attached</h1>' )
. attach ( 'report.pdf' , base64Content )
. send ()
} )
Add custom headers for tracking, routing, or other purposes:
server/api/custom-headers.ts
import { useLettermint } from '#imports'
export default defineEventHandler ( async () => {
const lettermint = useLettermint ()
return await lettermint . email
. from ( '[email protected] ' )
. to ( '[email protected] ' )
. subject ( 'Welcome' )
. html ( '<h1>Welcome to our app</h1>' )
. headers ({
'X-Campaign-ID' : 'welcome-2024' ,
'X-Priority' : 'high' ,
'X-Email-Type' : 'transactional'
})
. send ()
} )
Metadata is not sent in the email but stored by Lettermint for tracking and analytics:
server/api/tracked-email.ts
import { useLettermint } from '#imports'
export default defineEventHandler ( async () => {
const lettermint = useLettermint ()
return await lettermint . email
. from ( '[email protected] ' )
. to ( '[email protected] ' )
. subject ( 'Password Reset' )
. html ( '<h1>Reset your password</h1>' )
. metadata ({
userId: '12345' ,
action: 'password-reset' ,
ipAddress: '192.168.1.1' ,
userAgent: 'Mozilla/5.0...' ,
timestamp: new Date (). toISOString ()
})
. tag ( 'security' )
. send ()
} )
Metadata values must be strings. The module automatically converts objects to strings when using sendEmail(), but with the fluent API you should ensure values are strings.
How sendEmail() uses the fluent API
The sendEmail() function is implemented using the fluent API. Here’s how it works internally:
src/runtime/server/utils/lettermint.ts
export async function sendEmail ( options : SendEmailOptions ) {
const lettermint = useLettermint ()
let email = lettermint . email
. from ( options . from )
. subject ( options . subject )
// Add recipients (handling arrays)
if ( Array . isArray ( options . to )) {
options . to . forEach (( recipient ) => {
email = email . to ( recipient )
})
}
else {
email = email . to ( options . to )
}
// Add optional fields
if ( options . text ) email = email . text ( options . text )
if ( options . html ) email = email . html ( options . html )
// Handle CC (with array support)
if ( options . cc ) {
if ( Array . isArray ( options . cc )) {
options . cc . forEach (( recipient ) => {
email = email . cc ( recipient )
})
}
else {
email = email . cc ( options . cc )
}
}
// Handle BCC (with array support)
if ( options . bcc ) {
if ( Array . isArray ( options . bcc )) {
options . bcc . forEach (( recipient ) => {
email = email . bcc ( recipient )
})
}
else {
email = email . bcc ( options . bcc )
}
}
// Add tags
if ( options . tags ) {
options . tags . forEach (( tag ) => {
email = email . tag ( tag )
})
}
// Add headers
if ( options . headers ) {
email = email . headers ( options . headers )
}
// Add metadata
if ( options . metadata ) {
email = email . metadata ( options . metadata as Record < string , string >)
}
// Add attachments
if ( options . attachments ) {
options . attachments . forEach (( attachment ) => {
email = email . attach (
attachment . filename ,
typeof attachment . content === 'string'
? attachment . content
: attachment . content . toString ( 'base64' ),
)
})
}
return await email . send ()
}
When to use fluent API vs sendEmail()
Use sendEmail() when:
You have all email data upfront as an object
You’re working with form submissions or API requests
You want simple, straightforward email sending
You’re migrating from another email service
Use fluent API when:
You need to build emails conditionally
You want more explicit control over email composition
You’re working with complex email logic
You prefer a more expressive, chainable syntax
sendEmail() approach const result = await sendEmail ({
from: '[email protected] ' ,
to: recipients ,
subject: 'Update' ,
html: content ,
tags: [ 'newsletter' ]
})
Best for: Simple, data-driven emails
Fluent API approach let email = lettermint . email
. from ( '[email protected] ' )
. subject ( 'Update' )
recipients . forEach ( r => {
email = email . to ( r )
})
if ( isUrgent ) {
email = email . tag ( 'urgent' )
}
await email . send ()
Best for: Complex, conditional logic
Next steps
Custom endpoints Create custom API endpoints with additional logic
Configuration Learn about all configuration options