React Email

Build beautiful, responsive email templates with React Email and send them with Stack0.

Installation

Terminal
npm install @stack0/sdk @react-email/components react-email

Create an Email Template

Create a reusable email template component:

emails/welcome.tsx
import {
Body,
Container,
Head,
Heading,
Html,
Link,
Preview,
Text,
} from '@react-email/components'
interface WelcomeEmailProps {
name: string
loginUrl: string
}
export function WelcomeEmail({ name, loginUrl }: WelcomeEmailProps) {
return (
<Html>
<Head />
<Preview>Welcome to our platform, {name}!</Preview>
<Body style={main}>
<Container style={container}>
<Heading style={h1}>Welcome, {name}!</Heading>
<Text style={text}>
We're excited to have you on board. Get started by exploring
your dashboard.
</Text>
<Link href={loginUrl} style={button}>
Go to Dashboard
</Link>
<Text style={footer}>
If you didn't create an account, you can ignore this email.
</Text>
</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: '8px',
maxWidth: '600px',
}
const h1 = {
color: '#1a1a1a',
fontSize: '24px',
fontWeight: '600',
lineHeight: '1.25',
margin: '0 0 20px',
}
const text = {
color: '#4a4a4a',
fontSize: '16px',
lineHeight: '1.5',
margin: '0 0 20px',
}
const button = {
backgroundColor: '#000000',
borderRadius: '6px',
color: '#ffffff',
display: 'inline-block',
fontSize: '14px',
fontWeight: '600',
padding: '12px 24px',
textDecoration: 'none',
}
const footer = {
color: '#8a8a8a',
fontSize: '14px',
lineHeight: '1.5',
marginTop: '40px',
}

Render and Send

Render the template to HTML and send with Stack0:

lib/email.ts
import { Stack0 } from '@stack0/sdk'
import { render } from '@react-email/components'
import { WelcomeEmail } from '@/emails/welcome'
const stack0 = new Stack0({
apiKey: process.env.STACK0_API_KEY!
})
export async function sendWelcomeEmail(
email: string,
name: string,
loginUrl: string
) {
const html = await render(
WelcomeEmail({ name, loginUrl })
)
return await stack0.mail.send({
from: 'welcome@yourdomain.com',
to: email,
subject: `Welcome to our platform, ${name}!`,
html,
})
}

Order Confirmation Template

A more complex template with dynamic data:

emails/order-confirmation.tsx
import {
Body,
Container,
Column,
Head,
Heading,
Hr,
Html,
Preview,
Row,
Section,
Text,
} from '@react-email/components'
interface OrderItem {
name: string
quantity: number
price: number
}
interface OrderConfirmationProps {
orderNumber: string
customerName: string
items: OrderItem[]
total: number
}
export function OrderConfirmation({
orderNumber,
customerName,
items,
total,
}: OrderConfirmationProps) {
return (
<Html>
<Head />
<Preview>Your order #{orderNumber} has been confirmed</Preview>
<Body style={main}>
<Container style={container}>
<Heading style={h1}>Order Confirmed</Heading>
<Text style={text}>
Hi {customerName}, thank you for your order!
</Text>
<Text style={orderNum}>Order #{orderNumber}</Text>
<Hr style={hr} />
<Section>
{items.map((item, i) => (
<Row key={i} style={itemRow}>
<Column>
<Text style={itemName}>{item.name}</Text>
<Text style={itemQty}>Qty: {item.quantity}</Text>
</Column>
<Column align="right">
<Text style={itemPrice}>
${(item.price * item.quantity).toFixed(2)}
</Text>
</Column>
</Row>
))}
</Section>
<Hr style={hr} />
<Row>
<Column>
<Text style={totalLabel}>Total</Text>
</Column>
<Column align="right">
<Text style={totalAmount}>${total.toFixed(2)}</Text>
</Column>
</Row>
</Container>
</Body>
</Html>
)
}
const main = { backgroundColor: '#f6f9fc', fontFamily: 'sans-serif' }
const container = { backgroundColor: '#fff', margin: '0 auto', padding: '40px', maxWidth: '600px' }
const h1 = { color: '#1a1a1a', fontSize: '24px', margin: '0 0 20px' }
const text = { color: '#4a4a4a', fontSize: '16px', margin: '0 0 10px' }
const orderNum = { color: '#8a8a8a', fontSize: '14px', margin: '0 0 20px' }
const hr = { borderColor: '#e6e6e6', margin: '20px 0' }
const itemRow = { marginBottom: '10px' }
const itemName = { color: '#1a1a1a', fontSize: '14px', margin: '0' }
const itemQty = { color: '#8a8a8a', fontSize: '12px', margin: '0' }
const itemPrice = { color: '#1a1a1a', fontSize: '14px', margin: '0' }
const totalLabel = { color: '#1a1a1a', fontSize: '16px', fontWeight: '600', margin: '0' }
const totalAmount = { color: '#1a1a1a', fontSize: '18px', fontWeight: '600', margin: '0' }

Preview Emails Locally

Use the React Email dev server to preview templates:

package.json
{
"scripts": {
"email:dev": "email dev --dir emails"
}
}
Terminal
npm run email:dev

This opens a browser at localhost:3000 where you can preview and test your email templates.