$email
The $email tool provides a type-safe way to send emails and render Vue-based email templates in your Nuxt application. This tool is designed for Hex Labs organizational use and requires a valid HEXLABS_KEY environment variable.
Features
- Type-safe email sending with ArkType validation
- Vue component email templates using @vue-email/render
- Template-based emails with props support
- Plain text and HTML email generation
- Built-in error handling with Task pattern
Setup
First, define your email client with template components:
// app/appkit/$email.ts
import { defineEmail } from '#appkit/tools'
import InvoiceEmail from '~/components/emails/Invoice.vue'
import WelcomeEmail from '~/components/emails/Welcome.vue'
export const { $email } = defineEmail({
invoice: InvoiceEmail,
welcome: WelcomeEmail
})Environment Setup
Ensure you have the required environment variable:
HEXLABS_KEY="your-hexlabs-api-key"API Reference
$email.send(email)
Send a plain email with text or HTML content.
Parameters:
email- Email object with the following properties:from: string- Sender email (must be valid email)to: string | string[]- Recipient email(s) (must be valid email(s))subject: string- Email subject linemessage?: string- Plain text message (optional)html?: string- HTML content (optional)
Returns: Task<string> - Success message or error
const result = await $email.send({
from: 'noreply@example.com',
to: 'user@example.com',
subject: 'Welcome to our service',
message: 'Thank you for signing up!',
html: '<h1>Thank you for signing up!</h1>'
})
if (result.success) {
console.log(result.data) // "Email sent"
} else {
console.error(result.error)
}$email.sendTemplate(name, props, email)
Send an email using a Vue component template.
Parameters:
name: keyof Options- Template name (must match key in defineEmail options)props- Props object for the Vue component (type-safe based on component)email- Email metadata object:to: string | string[]- Recipient email(s)from: string- Sender emailsubject: string- Email subject line
Returns: Task<string> - Rendered HTML or error
const result = await $email.sendTemplate('invoice', {
customerName: 'John Doe',
invoiceNumber: 'INV-001',
amount: 99.99,
items: [
{ name: 'Product A', price: 49.99 },
{ name: 'Product B', price: 49.99 }
]
}, {
to: 'customer@example.com',
from: 'billing@example.com',
subject: 'Invoice INV-001'
})
if (result.success) {
console.log('Template email sent successfully')
} else {
console.error('Failed to send template email:', result.error)
}Vue Email Templates
Create Vue components for your email templates using @vue-email/components:
<!-- components/emails/Invoice.vue -->
<template>
<Html>
<Head>
<title>Invoice {{ invoiceNumber }}</title>
</Head>
<Preview>Invoice {{ invoiceNumber }} for {{ customerName }}</Preview>
<Body style="font-family: Arial, sans-serif;">
<Container style="max-width: 600px; margin: 0 auto;">
<Heading as="h1">Invoice {{ invoiceNumber }}</Heading>
<Text>Dear {{ customerName }},</Text>
<Text>Please find your invoice details below:</Text>
<Section>
<Row v-for="item in items" :key="item.name">
<Column>{{ item.name }}</Column>
<Column align="right">${{ item.price }}</Column>
</Row>
<Hr />
<Row>
<Column><strong>Total</strong></Column>
<Column align="right"><strong>${{ amount }}</strong></Column>
</Row>
</Section>
<Text>Thank you for your business!</Text>
</Container>
</Body>
</Html>
</template>
<script setup lang="ts">
interface Props {
customerName: string
invoiceNumber: string
amount: number
items: Array<{ name: string; price: number }>
}
defineProps<Props>()
</script>Template Rendering
The sendTemplate method automatically generates both HTML and plain text versions:
- HTML version: Full styled email with Vue component rendering
- Plain text version: Automatically extracted text content for email clients that don't support HTML
Error Handling
Both methods return a Task result that you should handle appropriately:
const emailResult = await $email.send(emailData)
if (!emailResult.success) {
// Handle validation errors
if (emailResult.code === 400) {
console.error('Invalid email data:', emailResult.error)
}
// Handle other errors
else {
console.error('Email sending failed:', emailResult.error)
}
}Validation
Email data is automatically validated using ArkType:
fromandtofields must be valid email addressestocan be a single email string or array of email stringssubjectis required and must be a non-empty stringmessageandhtmlare optional strings
Invalid data will return a validation error before attempting to send.
Integration
The email service integrates with the Hex Labs backend via the /api/hexlabs endpoint with service parameters:
service: "email"target: "send"
This allows for centralized email handling and delivery through the Hex Labs infrastructure.
Best Practices
- Environment Variables: Always set
HEXLABS_KEYin production - Template Organization: Keep email templates in a dedicated
components/emails/directory - Error Handling: Always check the Task result before assuming success
- Type Safety: Leverage TypeScript for template props and email data
- Preview: Use email preview tools to test templates before sending