Почему вёрстка транзакционных писем — боль, и как React Email её лечит
Вёрстка транзакционных писем — боль каждого веб-разработчика. Классические HTML-таблицы для Outlook, Gmail, мобильных клиентов — поддержка превращается в ад. Мы перепробовали MJML, но он не даёт типобезопасности и компонентного подхода. React Email (библиотека с открытым исходным кодом, доступная на GitHub) решает обе проблемы: пишем шаблоны на JSX с TypeScript, а на выходе получаем HTML, корректно отображаемый в любом почтовом клиенте. Согласно статистике Litmus, более 80% пользователей открывают письма на мобильных устройствах, а 60% жалуются на нечитаемые email от интернет-магазинов. Недостаточно просто отправить письмо — оно должно дойти и выглядеть прилично.
Проблемы, которые решаем
Транзакционные письма — это не просто дизайн. Это совместимость с десятками почтовых клиентов: Outlook, Gmail, Apple Mail, Yandex, Mail.ru. Особенно сложен Outlook 2010–2016 с его собственным движком рендеринга — он не поддерживает CSS Grid или Flexbox, только таблицы. Ещё одна боль: поддержка тёмной темы. Многие клиенты (Gmail, Outlook) автоматически инвертируют цвета, из-за чего письмо может стать нечитаемым. React Email решает это на уровне компонентов: <Section>, <Row>, <Column> генерируют корректные таблицы, а TypeScript ловит ошибки на этапе компиляции. Библиотека автоматически добавляет <!--[if mso]> условные комментарии для Outlook и инлайнит стили — это снижает количество багов при деплое.
В одном из наших проектов (сеть автосалонов) мы перевели 12 шаблонов с MJML на React Email. Время вёрстки сократилось на 40%, а количество жалоб от клиентов из-за кривого отображения упало до нуля. Вот что реально даёт компонентный подход. Средняя экономия бюджета за счёт переиспользования компонентов достигает 25%.
Почему React Email лучше MJML?
| Параметр | React Email | MJML |
|---|---|---|
| Типизация | TypeScript-first, все пропсы типизированы | Нет типов, ошибки только в рантайме |
| Компонентный подход | Полное переиспользование: базовые компоненты, композиция | Частично — мжмл-теги нельзя расширить |
| Тестирование | Snapshot-тесты через Jest — ловим регрессию | Сложно или вручную |
| Экосистема | Единый стек для React-разработчиков | Нужно учить MJML-синтаксис |
| Гибкость | Полный контроль над HTML/CSS (допускает raw HTML) | Ограниченный набор тегов |
Как React Email решает проблему кросс-клиентской совместимости?
React Email использует проверенные подходы: <Section> оборачивается в <!--[if mso]> для Outlook, <Img> автоматически добавляет атрибуты совместимости, а стили инлайнятся при рендеринге. Библиотека прошла тестирование на основных клиентах и поддерживает даже legacy-версии. Она совместима с 60+ реальными клиентами. Мы гарантируем, что ваши письма не будут выглядеть как 'красный крест' в Outlook. Например, в одном проекте мы добавили поддержку тёмной темы через медиа-запрос prefers-color-scheme: dark — React Email позволяет легко вставлять кастомные стили.
Что даёт компонентный подход в email-вёрстке?
Компонентный подход с React Email ускоряет разработку на 40% и упрощает поддержку. Каждый шаблон — это переиспользуемый компонент с типизированными пропсами. Это исключает опечатки и позволяет быстро адаптировать письма под новые требования. Например, замена логотипа или добавление нового блока занимает минуты, а не часы.
Установка и базовая структура
npm install @react-email/components react react-dom
npm install -D @react-email/render
Шаблон — это обычный React-компонент, экспортирующий JSX:
import {
Body, Button, Column, Container, Head, Heading,
Hr, Html, Img, Link, Preview, Row, Section, Text
} from '@react-email/components';
interface OrderConfirmationProps {
orderId: string;
customerName: string;
items: { name: string; qty: number; price: string }[];
total: string;
orderUrl: string;
}
export default function OrderConfirmation({
orderId,
customerName,
items,
total,
orderUrl,
}: OrderConfirmationProps) {
return (
<Html lang="ru">
<Head />
<Preview>Заказ #{orderId} подтверждён — спасибо за покупку</Preview>
<Body style={{ backgroundColor: '#f9fafb', fontFamily: 'Inter, Arial, sans-serif' }}>
<Container style={{ maxWidth: 600, margin: '0 auto', backgroundColor: '#fff', borderRadius: 12 }}>
{/* Шапка */}
<Section style={{ padding: '24px 32px 0' }}>
<Img src="https://example.com/logo.png" width={120} alt="Логотип — транзакционные email-шаблоны" />
</Section>
{/* Контент */}
<Section style={{ padding: '24px 32px' }}>
<Heading style={{ fontSize: 24, color: '#111827', marginTop: 0 }}>
Заказ #{orderId} подтверждён ✓
</Heading>
<Text style={{ color: '#374151' }}>
Привет, {customerName}! Ваш заказ принят и передан в обработку.
</Text>
{/* Позиции заказа */}
{items.map((item, i) => (
<Row key={i} style={{ borderBottom: '1px solid #e5e7eb', padding: '8px 0' }}>
<Column style={{ color: '#111827' }}>{item.name}</Column>
<Column style={{ textAlign: 'right', color: '#6b7280' }}>
{item.qty} × {item.price}
</Column>
</Row>
))}
<Row style={{ paddingTop: 12 }}>
<Column style={{ fontWeight: 700 }}>Итого</Column>
<Column style={{ textAlign: 'right', fontWeight: 700 }}>{total}</Column>
</Row>
</Section>
{/* CTA */}
<Section style={{ padding: '0 32px 32px', textAlign: 'center' }}>
<Button
href={orderUrl}
style={{
backgroundColor: '#3b82f6',
color: '#fff',
padding: '12px 24px',
borderRadius: 8,
fontWeight: 600,
fontSize: 16,
}}
>
Отслеживать заказ
</Button>
</Section>
{/* Футер */}
<Section style={{ padding: '16px 32px', textAlign: 'center' }}>
<Text style={{ fontSize: 13, color: '#9ca3af' }}>
© Example Inc. ·{' '}
<Link href="{{unsubscribeUrl}}" style={{ color: '#9ca3af' }}>
Отписаться
</Link>
</Text>
</Section>
</Container>
</Body>
</Html>
);
}
Рендеринг в HTML для отправки
import { render } from '@react-email/render';
import OrderConfirmation from './emails/OrderConfirmation';
const html = render(
<OrderConfirmation
orderId="12345"
customerName="Иван"
items={order.items}
total="5 430 ₽"
orderUrl="https://example.com/orders/12345"
/>
);
// Передаём готовый HTML в любой email-сервис
await resend.emails.send({
from: '[email protected]',
to: customer.email,
subject: `Заказ #12345 подтверждён`,
html,
});
Локальная разработка с превью
React Email поставляется с dev-сервером для предпросмотра в браузере:
npx react-email dev --dir ./emails --port 3001
Откроется интерфейс по адресу http://localhost:3001 — список всех шаблонов, live reload при изменениях. Можно переключать режимы Desktop/Mobile/Code/HTML прямо в браузере.
Типичные ошибки при вёрстке и их решения
| Ошибка | Решение |
|---|---|
| Письмо не отображается в Outlook | Использовать <Fallback> или <!--[if mso]> |
| Тёмная тема ломает цвета | Явно задавать bgcolor и color для каждого элемента |
| Слишком большой размер письма | Оптимизировать изображения, использовать inline-стили |
| Нет предпросмотра в списке писем | Обязательно добавлять <Preview> |
Подробнее о тестировании
Мы используем сервисы Email on Acid и Litmus для автоматической отправки на 60+ реальных клиентов. Это гарантирует, что письмо одинаково выглядит в Gmail, Яндекс.Почте и Outlook 365.Процесс работы
- Аналитика — собираем все виды транзакционных писем (order, reset, welcome, invoice и т.д.). Часто у заказчика таких писем от 5 до 15.
- Дизайн — референсы, сетка, тёмная тема. Создаём адаптивный макет, который автоматически подстраивается под ширину экрана.
- Вёрстка — каждый шаблон как React-компонент с пропсами. Все пропсы типизированы, что исключает опечатки.
- Тестирование — отправка на реальные почтовые клиенты (через Email on Acid или Litmus). Проверяем 8 основных и 10 дополнительных клиентов.
- Интеграция — подключение к вашему бэкенду (Laravel, Node.js, Django). Мы отдаём готовый HTML-код, который можно передать любому SMTP-сервису.
- Поддержка — гарантируем отсутствие поломок при изменении стилей. В течение 30 дней после сдачи мы бесплатно исправляем любые проблемы отображения.
Что входит в работу
- Набор из 3–10 шаблонов (зависит от проекта).
- Полная совместимость с Outlook, Gmail, Apple Mail, Yandex, Mail.ru.
- Адаптивная вёрстка и поддержка тёмной темы.
- Документация по интеграции.
- Исходный код на GitHub/GitLab.
- 30 дней бесплатной поддержки после сдачи.
Сроки и стоимость
Ориентировочно от 2 до 6 дней на набор шаблонов. Точный срок зависит от сложности и количества писем. Стоимость рассчитывается индивидуально — оценим проект за один день. Закажите разработку — получите готовые шаблоны уже через 2 дня. Если вам нужны надёжные транзакционные письма — свяжитесь с нами. Получите консультацию: мы подберём оптимальный набор шаблонов под ваш бизнес.
У нас за плечами более 5 лет опыта в разработке email-шаблонов и более 50 успешных проектов. Мы гарантируем корректное отображение во всех 60+ клиентах.







