Mail Service (Resend)
Overview
This guide explains how to send templated emails in a Vue/Nuxt application using VueMail for templating and Resend for delivery.
Components
1. Email Template
<!-- emails/templates/ExampleEmail.vue -->
<script setup lang="ts">
import { Text, Tailwind } from "@vue-email/components";
import BaseLayout from "@/emails/layouts/BaseLayout.vue";
defineProps({
recipient: String,
senderName: String,
// Other props needed for your email
});
</script>
<template>
<BaseLayout title="Email Subject" :recipient="recipient" previewText="Email preview text">
<Tailwind>
<Text class="text-base text-stone-600">
Hello {{ recipient }}, this is a message from {{ senderName }}.
</Text>
<!-- More content here -->
</Tailwind>
</BaseLayout>
</template>
2. API Route
// server/api/email/sendExample.ts
import exampleTemplate from "~/emails/templates/ExampleEmail.vue";
import { render } from "@vue-email/render";
import { Resend } from "resend";
const resend = new Resend(process.env.RESEND_API_KEY);
export default defineEventHandler(async (event) => {
const body = await readBody(event);
// Render email HTML using template and data
const emailHtml = await render(exampleTemplate, {
recipient: body.data.recipientName,
senderName: body.data.senderName,
// Pass other required props
}, {
pretty: true,
});
// Send email using Resend
const response = await resend.emails.send({
from: "Your App <emails@yourdomain.com>",
to: [body.data.recipientEmail],
subject: "Your Email Subject",
html: emailHtml,
});
// Handle errors
if (response.error) {
throw createError({
statusCode: 500,
statusMessage: response.error.message,
});
}
// Return success response
return {
sent: response.data?.id,
};
});
3. Front-end Implementation
<template>
<UButton :loading="loading" @click="sendEmail">
Send Email
</UButton>
</template>
<script setup lang="ts">
const loading = ref(false);
const data = ref({
recipientName: "John Doe",
recipientEmail: "recipient@example.com",
senderName: "Your App",
// Other data needed for the email
});
const sendEmail = async () => {
loading.value = true;
try {
const response = await $fetch("/api/email/sendExample", {
method: "POST",
body: {
data: data.value,
},
});
console.log("Email sent:", response.sent);
} catch (error) {
console.error("Error sending email:", error);
} finally {
loading.value = false;
}
};
</script>
Implementation Steps
- Install dependencies:
npm install @vue-email/render resend - Set up environment variables:
Add your Resend API key in
.envfile:RESEND_API_KEY=##_########## - Create email templates: Develop reusable Vue components for your email templates
- Create API endpoints: Build server endpoints to handle email rendering and sending
- Implement UI components: Add buttons or other UI elements to trigger email sending from the front-end
Best Practices
- Separate email content from delivery logic
- Use composition for reusable email components
- Handle loading states and errors properly
- Keep sensitive information in environment variables
- Validate input data before sending