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.
name: "Resend: send email on form submit",
run: async (payload, io, ctx) => {
await io.resend.sendEmail("send-email", {
subject: payload.subject,
// BasicEmail is the custom React component that will be used to style the email
react: <BasicEmail name={payload.name} text={payload.text} />,
backgroundColor: "#222094",
border: "solid 2px #dedede",
textAlign: "center" as const,
textAlign: "left" as const,
backgroundColor: "#28a745",
textAlign: "center" as const,
function BasicEmail({ name, text }: { name: string; text: string }) {
<Preview>Welcome to Acme Inc!</Preview>
<Container style={container}>
<Section style={section}>
href="https://acmecompany.inc/"
When the form is submitted the email is populated with the form content, the background job is triggered, and the email is sent.
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 = () => {
console.log(isSubmitted);
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);
className="flex flex-col gap-y-4 px-4 pb-4 sm:w-96 sm:px-0"
placeholder="Enter a 'to' email address"
className="text-charcoal-800 rounded p-1.5"
onChange={(e) => setTo(e.target.value)}
placeholder="Enter a subject"
className="text-charcoal-800 rounded p-1.5"
placeholder="Enter the name of the recipient"
className="text-charcoal-800 rounded p-1.5"
placeholder="Enter email text"
className="text-charcoal-800 rounded p-1.5"
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 "from" email address must be a verified domain in your
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"
<div className="flex gap-2">
className="text-charcoal-300 hover:text-charcoal-100 underline underline-offset-2 transition"
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.