Email transaksional dengan React Email, Resend, dan helper Mailpit lokal.
Email transaksional ada di packages/mail. Template berupa komponen React yang di-styling dengan Tailwind CSS lewat React Email, dirender ke HTML, lalu dikirim dengan sendEmail.
Mengapa React Email
Styling email dengan Tailwind seperti di aplikasi, compose potongan bersama
(misalnya Footer), dan preview template di server dev React Email.
Resend
Jalur production — yang dipakai sendEmail saat ini.
Mailpit
Capture SMTP lokal lewat Docker (helper ada; routing di-comment).
Mengirim email
Import sendEmail dari @repo/mail dan kirim template yang sudah dirender sebagai react:
import { sendEmail, MagicLinkSignIn } from "@repo/mail";
await sendEmail({
email: [user.email],
subject: "Sign in to TurboJet",
react: MagicLinkSignIn({
email: user.email,
url,
locale: "en",
copy: messages.magicLink,
}),
});SendEmailOptions (packages/mail/src/send-email.ts):
| Opsi | Tipe | Catatan |
|---|---|---|
email | string[] | Penerima |
subject | string | |
react | ReactElement | Komponen template yang sudah dirender |
from | string (opsional) | Default ke RESEND_EMAIL_DOMAIN |
Tidak ada registry nama template — Anda mengimpor komponen dan mengirim elemen sendiri.
Template
Template ada di packages/mail/src/emails:
MagicLinkSignIn.tsx— masuk/daftar tautan ajaibEmailOtpSignIn.tsx— kode sekali pakaicomponents/Footer.tsx— footer bersama; menginterpolasi{email}ke stringmessage
Setiap template menyusun @react-email/components (Html, Body, Container, Tailwind, …) secara langsung. Props berbagi bentuk yang sama: data email, locale opsional, dan objek copy berisi string yang sudah di-resolve.
Membuat template baru
- Tambahkan file
.tsxdipackages/mail/src/emails(tiru propcopytemplate yang ada). - Ekspor dari
packages/mail/src/index.ts. - Opsional: tambahkan subpath di
exportspackages/mail/package.json. - Tambahkan key copy di
packages/i18n/src/mail/en.jsondanid.json. - Panggil
sendEmaildengan komponen sebagaireact, kirimlocaledancopyyang sudah di-resolve.
Lihat dokumentasi React Email untuk komponen yang tersedia.
Terjemahan
Copy email ada di packages/i18n/src/mail/en.json dan id.json (magicLink, emailOtp). Template tidak memanggil createTranslator — pemanggil memuat string dengan getMailMessages(locale) dari @repo/i18n lalu mengirimnya sebagai copy.
import { getMailMessages } from "@repo/i18n";
const messages = await getMailMessages(locale);
// messages.magicLink → `copy` MagicLinkSignIngetMailMessages jatuh ke locale default untuk selain en / id.
Di mana dipakai
packages/auth/src/index.ts mengirim kedua email dari plugin Better Auth:
magicLink.sendMagicLink→MagicLinkSignInemailOTP.sendVerificationOTP(hanya type"sign-in") →EmailOtpSignIn
Locale di-resolve di resolveMailLocale(): cookie locale, lalu Accept-Language, lalu locale default. Lihat Autentikasi.
Preview email
Tidak ada app apps/mail-preview terpisah. Pakai script paket:
pnpm --filter @repo/mail devIni menjalankan email dev --dir src/emails --port 3003. Buka http://localhost:3003.