# Nuxt

## 1. Installation

<CodeTabs>
```bash title="nuxi (recommended)"
npx nuxi module add lettermint
```
```bash title="npm"
npm install nuxt-lettermint
```
```bash title="pnpm"
pnpm add nuxt-lettermint
```
```bash title="yarn"
yarn add nuxt-lettermint
```
</CodeTabs>

Add the module to `nuxt.config.ts`:

```typescript title="nuxt.config.ts"
export default defineNuxtConfig({
  modules: ['nuxt-lettermint']
})
```

## 2. Configuration

Set your API key in `.env`:

```env title=".env"
NUXT_LETTERMINT_API_KEY=your-api-key
```

Or configure directly in `nuxt.config.ts`:

```typescript title="nuxt.config.ts"
export default defineNuxtConfig({
  modules: ['nuxt-lettermint'],
  lettermint: {
    apiKey: 'your-api-key',
    autoEndpoint: true  // Creates /api/lettermint/send (default: true)
  }
})
```

:::warning
Never commit API keys to version control. Use environment variables in production.
:::

## 3. Send Your First Email

### Client-Side (Composable)

Use the `useLettermint` composable in Vue components:

```vue
<script setup lang="ts">
const { send, sending, error } = useLettermint()

async function sendWelcomeEmail() {
  await send({
    from: 'John Doe <john@yourdomain.com>',
    to: 'recipient@example.com',
    subject: 'Hello from Lettermint',
    text: 'This is a test email sent using the Lettermint Nuxt module.'
  })
}
</script>

<template>
  <button @click="sendWelcomeEmail" :disabled="sending">
    {{ sending ? 'Sending...' : 'Send Email' }}
  </button>
  <p v-if="error">{{ error }}</p>
</template>
```

### Server-Side (API Routes)

Send emails from Nitro server routes:

```typescript title="server/api/send-welcome.post.ts"
import { sendEmail } from '#imports'

export default defineEventHandler(async () => {
  return await sendEmail({
    from: 'John Doe <john@yourdomain.com>',
    to: 'recipient@example.com',
    subject: 'Welcome to our platform',
    html: '<h1>Welcome!</h1><p>Thanks for signing up.</p>',
    tags: ['welcome']
  })
})
```

### Fluent API

Build emails with a chainable API:

```typescript
const lettermint = useLettermint()

await lettermint.email
  .from('John Doe <john@yourdomain.com>')
  .to('recipient@example.com')
  .subject('Hello from Lettermint')
  .html('<h1>Hello!</h1>')
  .tag('welcome')
  .send()
```

## 4. Email Features

### HTML and Text Content

```typescript
await send({
  from: 'John Doe <john@yourdomain.com>',
  to: 'recipient@example.com',
  subject: 'Your account is ready!',
  html: '<h1>Welcome!</h1><p>Thanks for signing up.</p>',
  text: 'Welcome! Thanks for signing up.'
})
```

### Multiple Recipients

```typescript
await send({
  from: 'John Doe <john@yourdomain.com>',
  to: ['user1@example.com', 'user2@example.com'],
  cc: 'manager@yourdomain.com',
  bcc: 'archive@yourdomain.com',
  subject: 'Monthly Newsletter',
  html: '<h1>This Month\'s Updates</h1>'
})
```

### Reply-To and Custom Headers

```typescript
await send({
  from: 'support@yourdomain.com',
  to: 'customer@example.com',
  replyTo: 'help@yourdomain.com',
  subject: 'Support Ticket #12345',
  headers: {
    'X-Priority': '1',
    'X-Ticket-ID': '12345'
  },
  html: '<p>Your support ticket has been updated.</p>'
})
```

### Metadata

Attach data for tracking and webhook payloads:

```typescript
await send({
  from: 'notifications@yourdomain.com',
  to: 'user@example.com',
  subject: 'Order Confirmation',
  metadata: {
    orderId: 'ORD-12345',
    customerId: 'CUST-678'
  },
  html: '<p>Your order has been confirmed.</p>'
})
```

:::note
Metadata is included in webhook payloads but not sent to recipients.
:::

### Tags

Categorize emails for filtering and analytics:

<CodeTabs>
```typescript title="Object API"
await send({
  from: 'alerts@yourdomain.com',
  to: 'admin@example.com',
  subject: 'System Alert',
  tags: ['system-alerts'],
  html: '<p>Critical system alert detected.</p>'
})
```

```typescript title="Fluent API"
await lettermint.email
  .from('alerts@yourdomain.com')
  .to('admin@example.com')
  .subject('System Alert')
  .tag('system-alerts')
  .html('<p>Critical system alert detected.</p>')
  .send()
```
</CodeTabs>

:::note
One tag per message. The object API uses `tags` array, the fluent API uses `.tag()` method.
See [Tags documentation](/platform/emails/tags) for more details.
:::

### Attachments

<CodeTabs>
```vue title="Client-Side"
<script setup lang="ts">
const { send } = useLettermint()

async function sendWithAttachment(file: File) {
  const reader = new FileReader()

  reader.onload = async () => {
    const base64 = reader.result?.toString().split(',')[1]

    await send({
      from: 'invoices@yourdomain.com',
      to: 'customer@example.com',
      subject: 'Your Invoice',
      html: '<p>Please find your invoice attached.</p>',
      attachments: [{
        filename: file.name,
        content: base64
      }]
    })
  }

  reader.readAsDataURL(file)
}
</script>
```

```typescript title="Server-Side"
// server/api/send-invoice.post.ts
import fs from 'fs'
import { sendEmail } from '#imports'

export default defineEventHandler(async () => {
  const fileContent = fs.readFileSync('/path/to/invoice.pdf')
  const base64Content = fileContent.toString('base64')

  return await sendEmail({
    from: 'invoices@yourdomain.com',
    to: 'customer@example.com',
    subject: 'Your Invoice',
    html: '<p>Please find your invoice attached.</p>',
    attachments: [{
      filename: 'invoice.pdf',
      content: base64Content
    }]
  })
})
```
</CodeTabs>

## 5. Custom Endpoint

By default, the module creates an endpoint at `/api/lettermint/send`. Disable it for custom implementations:

```typescript title="nuxt.config.ts"
export default defineNuxtConfig({
  modules: ['nuxt-lettermint'],
  lettermint: {
    autoEndpoint: false
  }
})
```

Create your own endpoint with validation:

```typescript title="server/api/contact.post.ts"
import { sendEmail } from '#imports'

export default defineEventHandler(async (event) => {
  const body = await readBody(event)

  // Add your validation logic
  if (!body.email || !body.message) {
    throw createError({ statusCode: 400, message: 'Missing required fields' })
  }

  return await sendEmail({
    from: 'contact@yourdomain.com',
    to: 'support@yourdomain.com',
    subject: `Contact form: ${body.subject}`,
    html: `<p>From: ${body.email}</p><p>${body.message}</p>`,
    tags: ['contact-form']
  })
})
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Tags" icon="tag" href="/platform/emails/tags">
    Organize and filter emails with tags.
  </Card>
  <Card title="Tracking" icon="chart-line" href="/platform/emails/tracking/introduction">
    Track opens, clicks, and deliverability.
  </Card>
  <Card title="Webhooks" icon="webhook" href="/platform/webhooks/introduction">
    Receive real-time delivery notifications.
  </Card>
  <Card title="SMTP Alternative" icon="envelope" href="/guides/send-email-with-smtp">
    Send via SMTP instead of the API.
  </Card>
</CardGroup>

<Card title="GitHub Repository" icon="github" href="https://github.com/lettermint/nuxt-lettermint">
  Find the complete source code, report issues, or contribute on GitHub.
</Card>
