Skip to main content
Documentation

React Email templates

Build TSX templates with @react-email/components and use renderPreview to preview with variables in real time.

1. Install dependencies

Add @react-email/components to your project. Components are compatible with Node 18+.

bashbash
pnpm add @react-email/components @react-email/render

2. Create a TSX template

Write your template as a React component. Use dynamic variables as props — they will be substituted at send time.

templates/WelcomeEmail.tsx
import {  Body,  Container,  Head,  Heading,  Html,  Link,  Preview,  Text,} from '@react-email/components'; interface WelcomeEmailProps {  name: string;  activationUrl: string;} export function WelcomeEmail({ name, activationUrl }: WelcomeEmailProps) {  return (    <Html>      <Head />      <Preview>Bem-vindo ao CoffeeMail, {name}!</Preview>      <Body style={{ fontFamily: 'sans-serif', background: '#f6f6f6' }}>        <Container style={{ margin: '40px auto', padding: '20px', background: '#ffffff' }}>          <Heading style={{ color: '#1a1a1a' }}>Olá, {name}!</Heading>          <Text>Sua conta está quase pronta. Clique abaixo para ativar:</Text>          <Link href={activationUrl}>Ativar minha conta</Link>        </Container>      </Body>    </Html>  );}

3. Submit the HTML to CoffeeMail

Render the component with @react-email/render and POST to /v1/product/templates with format=react_email.

compile-and-save.ts
import { render } from '@react-email/render';import { WelcomeEmail } from './templates/WelcomeEmail'; const html = await render(  <WelcomeEmail name="{{ name }}" activationUrl="{{ activationUrl }}" />); const { data } = await coffeemail.templates.create({  name: 'welcome-email',  subject: 'Bem-vindo, {{ name }}!',  html,  format: 'react_email',  variables: [    { name: 'name', type: 'string', required: true },    { name: 'activationUrl', type: 'string', required: true },  ],});console.log('Template criado:', data.id);

4. Render preview

Use renderPreview to validate visually without sending — useful in the dashboard playground.

preview.ts
const { data } = await coffeemail.templates.renderPreview({  html: '<p>Olá, {{ name }}! Ative em {{ activationUrl }}</p>',  format: 'html',  variables: { name: 'Maria', activationUrl: 'https://app.seusite.com.br/ativar' },});console.log(data.html);

5. Use variables when sending

At send time, pass the variables object with the prop values. Missing variables fall back to the defaultValue registered in the template.

send.ts
await coffeemail.emails.send({  from: 'noreply@seudominio.com.br',  to: 'maria@example.com',  templateId: 'tpl_123',  variables: {    name: 'Maria',    activationUrl: 'https://app.seusite.com.br/ativar?token=xyz',  },});
The format: 'react' is rendered server-side by CoffeeMail from the HTML generated by @react-email/render — there is no JS bundle overhead in the sent email. The subject supports Handlebars ({name}) and is interpolated at send time.