Skip to main content
Attach files to your emails using the attachments array. Attachments support both string and Buffer content.

Basic attachment

Add a simple text file attachment:
import { sendEmail } from '#imports'

export default defineEventHandler(async () => {
  const result = await sendEmail({
    from: '[email protected]',
    to: '[email protected]',
    subject: 'Email with attachment',
    html: '<h1>Please see the attached file</h1>',
    attachments: [
      {
        filename: 'test.txt',
        content: 'Test attachment content'
      }
    ]
  })

  return { success: true, result }
})

Multiple attachments

Attach multiple files to a single email:
import { sendEmail } from '#imports'

export default defineEventHandler(async () => {
  const result = await sendEmail({
    from: '[email protected]',
    to: '[email protected]',
    subject: 'Multiple attachments',
    html: '<h1>Multiple files attached</h1>',
    attachments: [
      {
        filename: 'document.txt',
        content: 'Document content here'
      },
      {
        filename: 'data.json',
        content: JSON.stringify({ foo: 'bar' }, null, 2),
        contentType: 'application/json'
      }
    ]
  })

  return { success: true, result }
})

Buffer content

Use Buffer for binary file content:
import { sendEmail } from '#imports'
import { readFile } from 'fs/promises'

export default defineEventHandler(async () => {
  // Read file from filesystem
  const fileBuffer = await readFile('./path/to/file.pdf')

  const result = await sendEmail({
    from: '[email protected]',
    to: '[email protected]',
    subject: 'PDF attachment',
    html: '<h1>PDF file attached</h1>',
    attachments: [
      {
        filename: 'document.pdf',
        content: fileBuffer,
        contentType: 'application/pdf'
      }
    ]
  })

  return { success: true, result }
})

Content types

Specify the MIME type of your attachments using the contentType field:
import { sendEmail } from '#imports'

export default defineEventHandler(async () => {
  const result = await sendEmail({
    from: '[email protected]',
    to: '[email protected]',
    subject: 'Various file types',
    html: '<h1>Multiple file types attached</h1>',
    attachments: [
      {
        filename: 'data.json',
        content: JSON.stringify({ key: 'value' }),
        contentType: 'application/json'
      },
      {
        filename: 'style.css',
        content: 'body { margin: 0; }',
        contentType: 'text/css'
      },
      {
        filename: 'image.png',
        content: imageBuffer,
        contentType: 'image/png'
      }
    ]
  })

  return { success: true, result }
})
If you don’t specify a contentType, it will be inferred from the filename extension or default to text/plain.

Complete example with all options

Combine attachments with other email features:
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 }
})

Type definition

The attachment interface:
interface LettermintAttachment {
  filename: string
  content: string | Buffer
  contentType?: string
}

interface LettermintEmailOptions {
  // ... other fields
  attachments?: LettermintAttachment[]
}
Attachments are supported in both client-side and server-side email sending. However, be mindful of file sizes when sending from the client.

Next steps

Tags and metadata

Organize and track emails with tags and metadata

Configuration

Learn about all configuration options

Build docs developers (and LLMs) love