---
title: React email components
description: Use the document, card, heading, paragraph, action and divider components returned by a theme factory.
---

`themedReactEmailComponents(themeOrPreset?)` returns a component family. Pass `"light"`, `"dark"` or a `ReactEmailTheme`; the default preset is light.

| Component        | Special props                                         | Rendered structure                                                |
| ---------------- | ----------------------------------------------------- | ----------------------------------------------------------------- |
| `EmailDocument`  | `preview?`, `bodyStyle?`, HTML props including `lang` | HTML/head/body with theme styles and optional hidden preview text |
| `EmailCard`      | Table props including `style`                         | Presentation table containing the card content                    |
| `EmailHeading`   | `level?: 1 \| 2 \| 3`                                 | The corresponding heading element; level defaults to 1            |
| `EmailParagraph` | `tone?: "normal" \| "muted"`                          | Paragraph with normal or muted text styling                       |
| `EmailAction`    | Required `href`, `variant?: "solid" \| "outline"`     | Styled anchor; variant defaults to solid                          |
| `EmailDivider`   | Horizontal-rule props                                 | Themed separator                                                  |

Components also accept the corresponding native React element props. Style overrides are trusted host input, not sanitized design tokens. An action renders a link, not an authenticated operation.

## Shared recipe layout

The [template recipes](/ui) use this application helper to keep their structure consistent:

```ts
import { createElement } from "react";
import { themedReactEmailComponents } from "@corven/email-sdk/react";

const { EmailAction, EmailCard, EmailDocument, EmailHeading, EmailParagraph } =
  themedReactEmailComponents("light");

interface TransactionalEmailLayoutInput {
  readonly heading: string;
  readonly paragraphs: readonly string[];
  readonly preview: string;
  readonly action?: { readonly href: string; readonly label: string };
}

export const transactionalEmailLayout = (input: TransactionalEmailLayoutInput) =>
  createElement(
    EmailDocument,
    { lang: "en", preview: input.preview },
    createElement(
      EmailCard,
      null,
      createElement(EmailHeading, null, input.heading),
      ...input.paragraphs.map((text, index) => createElement(EmailParagraph, { key: index }, text)),
      input.action === undefined
        ? null
        : createElement(EmailAction, { href: input.action.href }, input.action.label),
    ),
  );
```

The helper is example code, not an SDK export. It creates trusted elements; `renderReactEmail` converts those elements into a body as shown in [React rendering](/integrations/react).

Hidden preview content is omitted from the renderer's plain-text conversion. Review both representations before submission. No component validates link origins, authorizes recipients or guarantees email-client rendering.
