Stop Writing Raw HTML Emails. Use React Email Templates Instead.
Build maintainable, responsive email templates using React Email instead of struggling with raw HTML tables. Includes password reset and order confirmation examples.
Transactional Team
Feb 1, 2026
>>
10 min read
Share
A common debugging nightmare in HTML email: a single <td> is missing a style attribute, and Outlook 2019 renders the entire layout in a single column. Hours lost for a missing inline style. On a <td>.
HTML email development is stuck in 2004. You write table-based layouts with inline styles because that is the only thing that works across Outlook, Gmail, Apple Mail, Yahoo, and the dozens of other clients that all render HTML differently. There is no Flexbox. There is no Grid. There is barely CSS.
React Email fixes this. You write React components, and it compiles them to battle-tested HTML that works everywhere.
What You Will Learn
Why HTML email is painful and how React Email solves it
Building a password reset email template
Building an order confirmation template
Preview and testing workflow
Integrating templates with a transactional email API
Run the dev server to preview your templates with hot reload:
npm run dev# Opens http://localhost:3000 with a live preview
The React Email dev server shows your templates with live data. You can toggle between desktop and mobile views, swap between light and dark mode, and change prop values in real time.
Test Across Email Clients
Before sending to real users, test in multiple clients:
# Export to static HTMLnpm run build# The exported HTML is in the 'out' directory# Upload to Litmus or Email on Acid for cross-client testing
Key clients to test:
Gmail (web and mobile) -- the most common
Apple Mail (macOS and iOS) -- generally the most forgiving
Outlook (desktop and web) -- the most problematic, uses Word's rendering engine
Yahoo Mail -- strips some CSS properties
Integrating with a Transactional Email API
Once your template is built, render it to HTML and send it through your email provider:
// send.tsimport { render } from '@react-email/components';import PasswordReset from './emails/password-reset';async function sendPasswordResetEmail( to: string, userName: string, resetToken: string) { // Render the React component to HTML const html = await render( PasswordReset({ userName, resetUrl: `https://app.example.com/reset?token=${resetToken}`, expiresIn: '1 hour', }) ); // Send via Transactional API const response = await fetch( 'https://api.transactional.so/email/send', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TRANSACTIONAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ from: 'noreply@example.com', to, subject: 'Reset your password', htmlBody: html, tag: 'password-reset', }), } ); if (!response.ok) { throw new Error(`Email send failed: ${response.statusText}`); }}
You can also generate a plain text version for accessibility:
import { render } from '@react-email/components';const html = await render(PasswordReset({ ...props }));const text = await render(PasswordReset({ ...props }), { plainText: true,});// Send both HTML and plain text versionsawait sendEmail({ htmlBody: html, textBody: text,});
Template Organization
For production, organize templates with shared components:
HTML email development is tedious, error-prone, and stuck in the past. React Email gives you components, props, TypeScript, and hot reload for email templates. You write modern React and get cross-client compatible HTML output.
The examples above cover the two most common transactional emails. Adapt the patterns for your welcome emails, invoice receipts, shipping notifications, and anything else your app sends.
If you are sending through Transactional's email API, the rendered HTML plugs directly into the htmlBody field. But the templates work with any email provider that accepts HTML input.