Overview
This guide will walk you through creating a complete email template using React Email, rendering it to HTML, and sending it with an email provider.
Install React Email
First, install the components package:npm install @react-email/components
Create Your First Email
Create a new file for your email template:import {
Body,
Container,
Head,
Heading,
Html,
Preview,
Text,
} from '@react-email/components';
interface WelcomeEmailProps {
name: string;
}
export const WelcomeEmail: React.FC<Readonly<WelcomeEmailProps>> = ({
name,
}) => (
<Html>
<Head />
<Body style={main}>
<Preview>
Welcome to our platform! We're excited to have you.
</Preview>
<Container style={container}>
<Heading style={h1}>Welcome aboard!</Heading>
<Text style={text}>
Hi {name}, thank you for joining our platform. We're excited to
have you on board and can't wait to see what you'll create.
</Text>
</Container>
</Body>
</Html>
);
export default WelcomeEmail;
const main = {
backgroundColor: '#ffffff',
fontFamily:
'-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif',
};
const container = {
margin: '0 auto',
padding: '20px 0 48px',
maxWidth: '560px',
};
const h1 = {
color: '#333',
fontSize: '24px',
fontWeight: '600',
lineHeight: '40px',
margin: '0 0 20px',
};
const text = {
color: '#666',
fontSize: '14px',
lineHeight: '24px',
margin: '0 0 40px',
};
The Preview component sets the preview text that appears in email clients before opening the email.
Preview Your Email
Start the development server to see your email in the browser:Open http://localhost:3000 to see your email with live reload.The dev server watches for file changes and automatically reloads, making it easy to iterate on your design.
Render to HTML
To send your email, you need to convert it to HTML using the render function:import { render } from '@react-email/components';
import { WelcomeEmail } from './emails/welcome';
const emailHtml = await render(<WelcomeEmail name="Alice" />);
The render function returns a Promise that resolves to an HTML string optimized for email clients.
Send Your Email
Now you can send the HTML with any email provider. Here’s an example with Nodemailer:import { render } from '@react-email/components';
import nodemailer from 'nodemailer';
import { WelcomeEmail } from './emails/welcome';
const transporter = nodemailer.createTransport({
host: 'smtp.forwardemail.net',
port: 465,
secure: true,
auth: {
user: 'my_user',
pass: 'my_password',
},
});
const emailHtml = await render(<WelcomeEmail name="Alice" />);
const options = {
from: '[email protected]',
to: '[email protected]',
subject: 'Welcome to our platform!',
html: emailHtml,
};
await transporter.sendMail(options);
Let’s enhance the email by adding a call-to-action button:
import {
Body,
Button,
Container,
Head,
Heading,
Html,
Preview,
Text,
} from '@react-email/components';
interface WelcomeEmailProps {
name: string;
loginUrl: string;
}
export const WelcomeEmail: React.FC<Readonly<WelcomeEmailProps>> = ({
name,
loginUrl,
}) => (
<Html>
<Head />
<Body style={main}>
<Preview>
Welcome to our platform! We're excited to have you.
</Preview>
<Container style={container}>
<Heading style={h1}>Welcome aboard!</Heading>
<Text style={text}>
Hi {name}, thank you for joining our platform. We're excited to
have you on board and can't wait to see what you'll create.
</Text>
<Button style={button} href={loginUrl}>
Get Started
</Button>
</Container>
</Body>
</Html>
);
export default WelcomeEmail;
const main = {
backgroundColor: '#ffffff',
fontFamily:
'-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif',
};
const container = {
margin: '0 auto',
padding: '20px 0 48px',
maxWidth: '560px',
};
const h1 = {
color: '#333',
fontSize: '24px',
fontWeight: '600',
lineHeight: '40px',
margin: '0 0 20px',
};
const text = {
color: '#666',
fontSize: '14px',
lineHeight: '24px',
margin: '0 0 10px',
};
const button = {
backgroundColor: '#5469d4',
borderRadius: '4px',
color: '#fff',
fontSize: '16px',
fontWeight: '600',
textDecoration: 'none',
textAlign: 'center' as const,
display: 'block',
padding: '12px 20px',
};
The button will render as a styled link that works reliably across all email clients.
Styling Best Practices
React Email components accept inline styles for maximum email client compatibility:
Use Inline Styles
Email clients have limited CSS support. Always use inline styles with the style prop.
Define Style Objects
Create reusable style objects for consistency and maintainability.
Avoid CSS Classes
Most email clients don’t support CSS classes. Stick to inline styles.
Use Tailwind (Optional)
The Tailwind component can convert utility classes to inline styles.
Common Email Patterns
import { Html, Button, Text, Container } from '@react-email/components';
export default function OrderConfirmation({ orderNumber, trackingUrl }) {
return (
<Html>
<Container>
<Text>Your order #{orderNumber} has shipped!</Text>
<Button href={trackingUrl}>Track Package</Button>
</Container>
</Html>
);
}
import { Html, Section, Heading, Text, Link } from '@react-email/components';
export default function Newsletter({ articles }) {
return (
<Html>
{articles.map((article) => (
<Section key={article.id}>
<Heading>{article.title}</Heading>
<Text>{article.excerpt}</Text>
<Link href={article.url}>Read more</Link>
</Section>
))}
</Html>
);
}
import { Html, Body, Container, Heading, Text, Button } from '@react-email/components';
export default function Welcome({ name, verifyUrl }) {
return (
<Html>
<Body>
<Container>
<Heading>Welcome {name}!</Heading>
<Text>Thanks for signing up. Please verify your email.</Text>
<Button href={verifyUrl}>Verify Email</Button>
</Container>
</Body>
</Html>
);
}
Working with Images
Add images using the Img component:
import { Img, Html, Container } from '@react-email/components';
export default function Email() {
return (
<Html>
<Container>
<Img
src="https://example.com/logo.png"
width="150"
height="50"
alt="Company Logo"
/>
</Container>
</Html>
);
}
Always use absolute URLs for images. Email clients don’t support relative paths.
Email Provider Integration
React Email works with all major email providers:
Resend
Modern email API with great React Email support
Nodemailer
Popular Node.js email sending library
SendGrid
Scalable email delivery platform
AWS SES
Amazon’s email sending service
Export to Static HTML
You can export all your emails to static HTML files:
This creates an out directory with HTML files for each email template.
Static exports are useful for version control, testing, or using with email systems that don’t support dynamic rendering.
Next Steps
Explore Components
Learn about all available React Email components
Render API
Advanced rendering options and configurations
Integrations
Set up React Email with your email provider
Examples
Browse real-world email template examples