Apprends à connecter Resend à ta boutique React Router 7 : installation du SDK, clé API, template HTML et envoi automatisé d’emails transactionnels.
avec React Router 7
Posez vos questions 24/7 à notre IA experte en React Router 7
Validez vos acquis avec des quiz personnalisés et un feedback instantané
Courier.com offre 10 000 envois gratuits mais :
Resend, lui :
Parfait pour notre boutique (faible volume). Si un jour tu dépasses plusieurs centaines de milliers de mails : passe à Mailgun ou Amazon SES.
1npm install resend
Le paquet ajoute juste un client HTTP. Aucun serveur à maintenir.
1RESEND_API_KEY=__TA_CLE__2RESEND_FROM_EMAIL=contact@shop-router.algomax.fr
RESEND_API_KEY
: copiée dans Dashboard → API keys.RESEND_FROM_EMAIL
: domaine vérifié côté Resend..env
(il est déjà dans .gitignore
).1import { Resend } from "resend";23export const resend = new Resend(process.env.RESEND_API_KEY);
Simple : une instance, typée, prête à envoyer.
On crée un modèle HTML + fallback texte.
Seule donnée dynamique : OrderEmailData
.
1interface OrderEmailData {2orderId: string;3customerName: string;4customerEmail: string;5orderItems: Array<{6productName: string;7quantity: number;8totalPriceCents: number;9}>;10subtotalCents: number;11totalCents: number;12currency: string;13orderDate: Date;14}1516const orderConfirmationTemplate = (d: OrderEmailData) => `17<h1 style="font-size:22px;margin:0 0 12px">✅ Commande confirmée</h1>18<p>Merci ${d.customerName} !</p>19<p>N° ${d.orderId} — ${d.orderDate.toLocaleDateString("fr-FR")}</p>20${d.orderItems21.map(22(i) =>23`<p>${i.productName} ×${i.quantity} — ${format(i.totalPriceCents, d.currency)}</p>`,24)25.join("")}26<p style="font-weight:bold">Total : ${format(d.totalCents, d.currency)}</p>27<a href="${process.env.FRONTEND_URL}/orders/${d.orderId}"28style="display:inline-block;padding:12px 24px;background:#2563eb;color:#fff;border-radius:6px">29Suivre ma commande30</a>31`;3233const format = (cents: number, currency: string) =>34new Intl.NumberFormat("fr-FR", { style: "currency", currency }).format(cents / 100);
1export async function sendOrderConfirmationEmail(data: OrderEmailData) {2await resend.emails.send({3from: process.env.RESEND_FROM_EMAIL!,4to: data.customerEmail,5subject: `Confirmation de commande #${data.orderId}`,6html: orderConfirmationTemplate(data),7text: `Merci ${data.customerName}. Commande ${data.orderId}. Total : ${format(8data.totalCents,9data.currency,10)}`,11});12}
from
: adresse vérifiée.to
: le client.subject
: clair et unique (numéro de commande).1await prisma.order.update({ … });2await sendOrderConfirmationEmail({3orderId: order.id,4customerName: user?.name ?? "client",5customerEmail: user?.email ?? guestEmail!,6orderItems: order.items,7subtotalCents: order.subtotalCents,8totalCents: order.totalCents,9currency: order.currency,10orderDate: order.createdAt,11});
Pourquoi ici ?
npm run dev
.Le même fichier contient déjà :
sendOrderStatusUpdateEmail()
sendPasswordResetEmail()
sendAccountCreatedEmail()
Ils partagent la même logique : template HTML + fallback texte. Tu pourras les appeler :
1// après changement de statut2await sendOrderStatusUpdateEmail({ … });34// lors de la création du compte (hook Better-Auth)5await sendAccountCreatedForUser(email, name);
RESEND_API_KEY
+ RESEND_FROM_EMAIL
présents en production (Settings → Secrets GitHub
).Commit :
1git add .2git commit -m "feat: emails transactionnels via Resend"3git push --set-upstream origin 7-16-envoi-emails-resend
La CI relance, ton VPS reçoit la nouvelle image ; les prochains clients recevront immédiatement leur confirmation de commande 📧.
Quelle est la principale différence entre les composants client et serveur dans React ?
Quelle technique est recommandée pour éviter les rendus inutiles dans React ?
Quel hook permet de gérer les effets de bord dans un composant React ?
Comment implémenter la gestion des erreurs pour les requêtes API dans React ?
Quelle est la meilleure pratique pour déployer une application React en production ?