# BlockNote to Email-Safe HTML Exporter ## Overview Messages uses [BlockNote](https://www.blocknotejs.org/) as its rich-text editor. BlockNote's built-in `blocksToHTMLLossy` produces HTML that relies on CSS classes and modern layout which email clients strip or ignore. The **EmailExporter** converts BlockNote's block tree into HTML that is safe for email rendering: every style is **inline**, images reference **cid:** URLs for MIME embedding, and layout is achieved through `` wrappers generated by [@react-email/components](https://react.email/). ``` src/frontend/src/features/blocknote/email-exporter/ ├── index.tsx # Exporter implementation └── index.test.tsx # Test suite ``` ## Architecture ### Conversion pipeline ``` BlockNote blocks (JSON) │ ▼ transformBlocks() ← Groups consecutive list items, recurses children │ ▼ React nodes ← Using @react-email/components (Section, Text, Img…) │ ▼ renderToStaticMarkup() ← react-dom/server, no hydration markers │ ▼ Email-safe HTML string ``` ### Public API ```ts import { EmailExporter } from '@/features/blocknote/email-exporter'; const exporter = new EmailExporter(); const html = exporter.exportBlocks( blocks, // BlockNote document blocks editorDomElement, // Editor DOM element (for image width fallback), nullable ); ``` ### Integration points | Caller | File | Notes | |--------|------|-------| | Message send | `message-composer/index.tsx` via `exportContent()` ref | Called at send time, not on every keystroke | | Signature editor | `hooks/use-base64-composer.tsx` | Object URLs resolved to base64 after export | | Template editor | `hooks/use-base64-composer.tsx` | Same hook, shared with signatures | Export is intentionally **deferred to send/save time** to avoid the cost of `blocksToMarkdownLossy()` (which creates real DOM elements) on every keystroke. ## Supported blocks ### Content blocks | BlockNote type | HTML output | Styling | |---|---|---| | `paragraph` | `

` (via ``) | textAlignment, textColor, backgroundColor | | `heading` | `

`–`

` (via ``) | level, textAlignment, textColor, backgroundColor | | `quote` | `
` with left border | textAlignment, textColor, backgroundColor | | `codeBlock` | `
` | Grey background, rounded corners |
| `divider` | `
` (via `
`) | — | ### List blocks Consecutive list items of the same type are grouped into a single `