Верстка писем с использованием React
Сверстать письмо хорошо, так чтобы оно корректно отображалось во всех почтовых клиентах, на десктопе и мобильных устройствах, не так просто.
Для надо знать нюансы того как почтовые клиенты возможности
CSS и HTML. Чтобы не выяснять это на практике, можно пользоваться сайтом Can I email,
где можно посмотреть поддержку различных тегов и атрибутов в различных почтовых клиентах.
Вот, например, Gmail отбрасывает аттрибут style
целиком, если встречает
в нем цвет заданный как rgb
.
В итоге даже в 2025 году верстка писем сводится к использованию таблиц и аттрибутов align
, valign
, bgcolor
и т.д.
Ну а еще отправив письмо, вы не можете его поправить, как страницу на сайте.
Поэтому я оценил библиотеку React Email, которая позволяет создавать письма с использованием React. Она предоставляет компоненты, которые генерируют HTML и CSS, корректно отображающиеся во всех почтовых клиентах. Письмо можно посмотреть в браузере и отправить на почту. Да, под капотом все равно используются таблицы, но зато вам не придется их писать руками, а можно использовать более высокоуровневые абстракции.
Установка
Для начала установите библиотеку @react-email/components
и клиент для работы с почтовым сервисом AWS SESv2, потому что
Postbox поддерживает именно эту версию клиента.
npm install @aws-sdk/client-sesv2 @react-email/components
Создание письма
Создайте компонент, который будет генерировать письмо. Например, так:
import * as React from 'react';
import { Button, Html } from '@react-email/components';
export function Email(props) {
const { url } = props;
return (
<Html lang="en">
<Button href={url}>Click me</Button>
</Html>
);
}
Больше компонентов можно посмотреть в документации.
Создание сервисного аккаунта
- Создайте сервисный аккаунт в том же каталоге, в котором находится адрес. Если вы создадите сервисный аккаунт и адрес в разных каталогах, при попытке отправить письмо возникнет ошибка.
- Назначьте сервисному аккаунту роль
postbox.sender
. - Для отправки письма с помощью SDK создайте статический ключ доступа. Надежно сохраните идентификатор и секретный ключ. После того как вы закроете окно, параметры секретного ключа станут недоступны.
Отправка письма
Для отправки письма используйте Postbox. Он позволяет отправлять письма, созданные с помощью React Email, через AWS SESv2 SDK.
Ключи доступа можно передать в конструктор SESv2Client
явно, как показано ниже, указать их в переменных окружения или
использовать конфигурацию AWS CLI.
import { render } from '@react-email/components';
import type { SendEmailCommandInput } from '@aws-sdk/client-sesv2';
import { SendEmailCommand, SESv2Client } from '@aws-sdk/client-sesv2';
import { Email } from './email';
import React from 'react'
const sesClient = new SESv2Client({
region: 'ru-central1',
endpoint: 'https://postbox.cloud.yandex.net',
});
const emailHtml = await render(<Email url="https://example.com"/>);
const emailText = await render(<Email url="https://example.com"/>, {
pretty: true,
plainText: true,
});
const email: SendEmailCommandInput = {
Content: {
Simple: {
Headers: [
{
Name: 'List-Unsubscribe',
Value: `<https://example.com/unsubscribe/subscriptionId>`,
},
{
Name: 'List-Unsubscribe-Post',
Value: 'List-Unsubscribe=One-Click',
}
],
Body: {
Html: {
Data: emailHtml,
},
Text: {
Data: emailText,
},
},
Subject: {
Data: 'Тестовое письмо',
},
},
},
Destination: {
ToAddresses: [
'bob@example.com'
],
},
FromEmailAddress: 'Alice <alice@example.com>',
}
const command = new SendEmailCommand(email);
const result = await sesClient.send(command);
console.log(result);
Чтобы удобно запускать скрипт установите tsx
loader:
npm install --save-dev tsx
Теперь запустите скрипт, передав в переменные окружения ключи сервисного аккаунта:
AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... node --import @nodejs-loaders/tsx index.tsx
В консоли вы увидите ответ от Postbox. Если письмо отправлено успешно, то в ответе будет MessageId
.
{
'$metadata': {
httpStatusCode: 200,
requestId: undefined,
extendedRequestId: undefined,
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
},
MessageId: 'D8BT2CX3IDK2.2HZQ4CE0E8CRL@ingress1-sas'
}
Если вы хотите отправить несколько писем в цикле, то рекомендую добавить в код задержку между отправками, чтобы не превысить квоту на скорость отправки писем.