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 stylingconst 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 "from" 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.