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

  1. Install dependencies:
    npm install @vue-email/render resend
    
  2. Set up environment variables: Add your Resend API key in .env file:
    RESEND_API_KEY=##_##########
    
  3. Create email templates: Develop reusable Vue components for your email templates
  4. Create API endpoints: Build server endpoints to handle email rendering and sending
  5. 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