Send an email with Resend when a form is submitted

Send an email with Resend when a form is submitted

Trigger: eventTrigger

Sends an email using Resend when a form is submitted. The email is built using React and the data from the form.

Framework:

APIs used:

Repository:

/resend-email-form

Categories:

Marketing

Overview

In this project the user can submit a form which triggers a background job which sends an email using Resend. The email is built using React and the data from the form.

To get started with this project follow the instructions on the GitHub README page.

Key features:

  • Sending a React email using our Resend integration.
  • A form which triggers the background job when submitted.

Sending a React email using our Resend integration

The email is built using React, styled with CSS and sent using our Resend integration.

sendReactEmail.tsx

client.defineJob({
id: "resend-email-form",
name: "Resend: send email on form submit",
version: "1.0.0",
trigger: eventTrigger({
name: "send.email",
schema: z.object({
to: z.string(),
subject: z.string(),
text: z.string(),
name: z.string(),
from: z.string(),
}),
}),
integrations: {
resend,
},
run: async (payload, io, ctx) => {
await io.resend.sendEmail("send-email", {
to: payload.to,
subject: payload.subject,
text: payload.text,
from: payload.from,
// BasicEmail is the custom React component that will be used to style the email
react: <BasicEmail name={payload.name} text={payload.text} />,
});
},
});
// Email styling
const main = {
padding: "10px 0",
backgroundColor: "#222094",
};
const container = {
margin: "0 auto",
padding: "20px 0 48px",
};
const section = {
padding: "24px",
border: "solid 2px #dedede",
backgroundColor: "#fff",
borderRadius: "5px",
textAlign: "center" as const,
};
const text = {
textAlign: "left" as const,
fontSize: "16px",
};
const button = {
fontSize: "14px",
font: "bold",
backgroundColor: "#28a745",
color: "#fff",
lineHeight: 1.5,
borderRadius: "0.2em",
textAlign: "center" as const,
};
function BasicEmail({ name, text }: { name: string; text: string }) {
return (
<Html>
<Head />
<Preview>Welcome to Acme Inc!</Preview>
<Body style={main}>
<Container style={container}>
<Section style={section}>
<Text>Hey {name}!</Text>
<Text>{text}</Text>
<Button
style={button}
pY={4}
pX={4}
href="https://acmecompany.inc/"
>
Get started
</Button>
</Section>
</Container>
</Body>
</Html>
);
}

A form which triggers the background job when submitted

When the form is submitted the email is populated with the form content, the background job is triggered, and the email is sent.

sendEmailForm.tsx

"use client";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { sendEmail } from "../_actions";
const SendEmailForm = () => {
const [isSubmitted, setIsSubmitted] = useState(false);
const [to, setTo] = useState("");
const [from, setFrom] = useState("");
const router = useRouter();
const handleRefresh = () => {
setIsSubmitted(false);
console.log(isSubmitted);
router.refresh();
};
async function action(data: FormData) {
const to = data.get("to");
if (typeof to !== "string" || !to) return;
const subject = data.get("subject");
if (typeof subject !== "string" || !subject) return;
const name = data.get("name");
if (typeof name !== "string" || !name) return;
const text = data.get("text");
if (typeof text !== "string" || !text) return;
const from = data.get("from");
if (typeof from !== "string" || !from) return;
//send the event to trigger the email.
//You can use the returned event with the @trigger.dev/react package if you want more detailed Job progress in your UI
const event = await sendEmail(to, subject, name, text, from);
setIsSubmitted(true);
}
return (
<form
action={action}
className="flex flex-col gap-y-4 px-4 pb-4 sm:w-96 sm:px-0"
>
<input
type="text"
name="to"
placeholder="Enter a 'to' email address"
className="text-charcoal-800 rounded p-1.5"
value={to}
onChange={(e) => setTo(e.target.value)}
/>
<input
type="text"
name="subject"
placeholder="Enter a subject"
className="text-charcoal-800 rounded p-1.5"
/>
<input
type="text"
name="name"
placeholder="Enter the name of the recipient"
className="text-charcoal-800 rounded p-1.5"
/>
<textarea
name="text"
placeholder="Enter email text"
className="text-charcoal-800 rounded p-1.5"
/>
<input
type="text"
name="from"
placeholder="Enter a 'from' email address"
className="text-charcoal-800 rounded p-1.5"
onChange={(e) => setFrom(e.target.value)}
/>
<p className="text-sm text-gray-500">
⚠️ The &quot;from&quot; email address must be a verified domain in your
Resend account to work.
</p>
{!isSubmitted ? (
<button
type="submit"
disabled={!isValidEmail(to) || !isValidEmail(from)}
className="bg-lavender-600 hover:bg-lavender-500 mt-2 h-10 w-full rounded font-bold transition disabled:opacity-20"
>
✉️ Send email
</button>
) : (
<div className="flex gap-2">
<p>✅ Email sent! - </p>
<button
onClick={handleRefresh}
className="text-charcoal-300 hover:text-charcoal-100 underline underline-offset-2 transition"
>
Send another
</button>
</div>
)}
</form>
);
};
function isValidEmail(email: string) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
export default SendEmailForm;

How to run this project

Follow the instructions on the GitHub README page.