Templates con React Email

React Email es una librería para escribir emails usando componentes de React en lugar del clásico HTML con tablas anidadas. Fue creada por el mismo equipo detrás de Resend (Zeno Rocha) y está diseñada para integrarse directamente con su API.

La idea es simple: si ya sabes escribir componentes de React, puedes escribir emails sin tocar una sola tabla HTML.

Por qué React Email

Escribir emails en HTML puro es una experiencia terrible. Los clientes de email (Gmail, Outlook, Apple Mail) renderizan HTML de forma inconsistente, y la única forma confiable de hacer layouts es con tablas anidadas y estilos inline. React Email resuelve esto:

  • Componentes reutilizables: escribes un template una vez y lo usas en cualquier parte de tu app
  • Estilos inline automáticos: defines estilos como objetos de React y React Email los convierte a estilos inline compatibles
  • Responsivo sin dolor: los componentes manejan la compatibilidad entre clientes por ti
  • Preview en desarrollo: ves tus emails en el navegador mientras los construyes

Instalación

bash
npm install @react-email/components

Tu primer template

Crea una carpeta /emails/ en la raíz de tu proyecto. Ahí van todos tus templates. Aquí tienes un ejemplo de email de bienvenida:

tsx
import {
  Html,
  Head,
  Body,
  Container,
  Text,
  Button,
  Hr,
  Preview,
} from '@react-email/components'
 
interface WelcomeEmailProps {
  nombre: string
  loginUrl: string
}
 
export function WelcomeEmail({ nombre, loginUrl }: WelcomeEmailProps) {
  return (
    <Html>
      <Head />
      <Preview>Bienvenido a nuestra plataforma</Preview>
      <Body style={{ backgroundColor: '#f6f9fc', fontFamily: 'sans-serif' }}>
        <Container style={{ maxWidth: '600px', margin: '0 auto', padding: '20px' }}>
          <Text style={{ fontSize: '24px', fontWeight: 'bold' }}>
            Hola {nombre}
          </Text>
          <Text>Tu cuenta fue creada exitosamente.</Text>
          <Button
            href={loginUrl}
            style={{
              backgroundColor: '#000',
              color: '#fff',
              padding: '12px 24px',
              borderRadius: '6px',
            }}
          >
            Iniciar sesión
          </Button>
          <Hr />
          <Text style={{ color: '#666', fontSize: '12px' }}>
            Si no creaste esta cuenta, ignora este email.
          </Text>
        </Container>
      </Body>
    </Html>
  )
}

El template es un componente de React normal. Recibe props tipadas con TypeScript y retorna JSX usando los componentes de @react-email/components.

Usar el template con Resend

Una vez que tienes tu template, enviarlo con Resend es una línea:

typescript
import { Resend } from 'resend'
import { WelcomeEmail } from '@/emails/welcome'
 
const resend = new Resend(process.env.RESEND_API_KEY)
 
await resend.emails.send({
  from: 'Mi App <noreply@midominio.com>',
  to: ['usuario@ejemplo.com'],
  subject: 'Bienvenido a Mi App',
  react: WelcomeEmail({ nombre: 'Juan', loginUrl: 'https://miapp.com/login' }),
})
El campo react acepta componentes directamente

No necesitas renderizar el HTML manualmente. El campo react acepta un componente de React y Resend se encarga de renderizarlo a HTML compatible con todos los clientes de email.

Preview en desarrollo

React Email incluye un servidor de desarrollo para previsualizar tus templates en el navegador:

bash
npx react-email dev

Esto abre una interfaz en http://localhost:3000 donde puedes ver cada template renderizado, cambiar props de prueba y verificar cómo se ve antes de enviarlo.

Convención de carpeta

La convención recomendada es crear una carpeta /emails/ en la raíz de tu proyecto:

plaintext
mi-proyecto/
├── emails/
│   ├── welcome.tsx
│   ├── reset-password.tsx
│   ├── invoice.tsx
│   └── notification.tsx
├── app/
├── lib/
└── package.json

Cada archivo exporta un componente que representa un template de email.

Estilos en React Email

React Email usa estilos inline (objetos de React) porque es la única forma confiable de aplicar estilos en todos los clientes de email. Defines los estilos como objetos de JavaScript:

tsx
<Text style={{ fontSize: '16px', color: '#333', lineHeight: '1.5' }}>
  Este texto se renderiza con estilos inline.
</Text>

Puedes extraer estilos a constantes para reutilizarlos:

tsx
const styles = {
  heading: {
    fontSize: '24px',
    fontWeight: 'bold' as const,
    color: '#111',
  },
  paragraph: {
    fontSize: '16px',
    color: '#333',
    lineHeight: '1.5',
  },
}
No uses Tailwind CSS en emails

La mayoría de clientes de email (Gmail, Outlook) ignoran clases CSS externas. React Email tiene un componente Tailwind experimental, pero no es confiable en producción. Usa estilos inline para garantizar compatibilidad.