← Back to list

create-email
by tech-with-seth
React Router 7 starter with Polar.sh, BetterAuth, Prisma, and Tailwind
⭐ 1🍴 0📅 Jan 24, 2026
SKILL.md
name: create-email description: Create email templates with React Email and Resend integration. Use when building transactional emails, notification templates, or integrating email sending functionality.
Create Email
Creates email templates using React Email and sends them via Resend, following Iridium's three-layer architecture.
When to Use
- Creating transactional email templates (welcome, password reset, notifications)
- Adding email sending functionality to routes
- Integrating email with webhooks or actions
- User asks to "send email", "create email template", or "add notifications"
Architecture
Client/Server Code
↓
Model Layer (app/models/email.server.ts)
↓
Resend SDK (app/lib/resend.server.ts)
Never call Resend SDK directly in routes. Always use model layer functions.
Step 1: Create Email Template
Location: app/emails/[template-name].tsx
// app/emails/order-confirmation.tsx
import {
Body,
Button,
Container,
Head,
Heading,
Html,
Preview,
Text,
} from '@react-email/components';
interface OrderConfirmationProps {
customerName: string;
orderNumber: string;
orderUrl: string;
}
export default function OrderConfirmation({
customerName,
orderNumber,
orderUrl,
}: OrderConfirmationProps) {
return (
<Html>
<Head />
<Preview>Your order #{orderNumber} has been confirmed</Preview>
<Body style={main}>
<Container style={container}>
<Heading style={heading}>Order Confirmed!</Heading>
<Text style={text}>Hi {customerName},</Text>
<Text style={text}>
Your order #{orderNumber} has been confirmed.
</Text>
<Button href={orderUrl} style={button}>
View Order
</Button>
</Container>
</Body>
</Html>
);
}
const main = {
backgroundColor: '#f6f9fc',
fontFamily: '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif',
};
const container = {
backgroundColor: '#ffffff',
margin: '0 auto',
padding: '40px',
borderRadius: '4px',
};
const heading = {
fontSize: '24px',
fontWeight: 'bold',
marginBottom: '20px',
};
const text = {
fontSize: '16px',
lineHeight: '24px',
marginBottom: '16px',
};
const button = {
backgroundColor: '#5046e5',
borderRadius: '4px',
color: '#fff',
fontSize: '16px',
textDecoration: 'none',
padding: '12px 24px',
display: 'inline-block',
};
Step 2: Add Model Layer Function
Location: app/models/email.server.ts
import { render } from '@react-email/components';
import OrderConfirmation from '~/emails/order-confirmation';
import { sendEmail } from './email.server';
export async function sendOrderConfirmation({
to,
customerName,
orderNumber,
orderUrl,
}: {
to: string;
customerName: string;
orderNumber: string;
orderUrl: string;
}) {
const html = await render(
OrderConfirmation({
customerName,
orderNumber,
orderUrl,
}),
);
return sendEmail({
to,
subject: `Order Confirmation #${orderNumber}`,
html,
});
}
Step 3: Use in Routes
import type { Route } from './+types/order';
import { sendOrderConfirmation } from '~/models/email.server';
export async function action({ request }: Route.ActionArgs) {
const user = await requireUser(request);
const order = await createOrder(data);
// Send confirmation email
await sendOrderConfirmation({
to: user.email,
customerName: user.name,
orderNumber: order.id,
orderUrl: `${process.env.BETTER_AUTH_URL}/orders/${order.id}`,
});
return data({ success: true });
}
Existing Model Layer Functions
Available in app/models/email.server.ts:
| Function | Purpose |
|---|---|
sendEmail(options) | Send raw HTML/text email |
sendVerificationEmail({ to, verificationUrl }) | BetterAuth verification |
sendPasswordResetEmail({ to, resetUrl }) | BetterAuth password reset |
sendWelcomeEmail({ to, userName, dashboardUrl }) | Onboarding |
sendTransactionalEmail({ to, heading, message }) | Generic notifications |
sendBatchEmails(emails) | Bulk sending |
Environment Variables
RESEND_API_KEY="re_your-resend-api-key-here"
RESEND_FROM_EMAIL="noreply@yourdomain.com" # Optional
Testing Locally
# Preview templates
npx react-email dev
Use onboarding@resend.dev as sender during development.
Anti-Patterns
- Calling
resend.emails.send()directly in routes - Sending emails without user authentication
- Exposing API keys with
VITE_prefix - Sending unvalidated recipient addresses
- Missing error handling for email failures
Full Reference
See .github/instructions/resend.instructions.md for comprehensive documentation.
Score
Total Score
65/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
✓最近の活動
1ヶ月以内に更新
+10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
✓タグ
1つ以上のタグが設定されている
+5
Reviews
💬
Reviews coming soon

