| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- import { pageMetadata } from "@/lib/page-metadata"
- export const metadata = pageMetadata("docs/api/react-email")
- # @json-render/react-email
- React Email renderer. Turn JSON specs into HTML or plain-text emails using `@react-email/components` and `@react-email/render`.
- ## Install
- ```bash
- npm install @json-render/core @json-render/react-email @react-email/components @react-email/render
- ```
- See the [React Email example](https://github.com/vercel-labs/json-render/tree/main/examples/react-email) for a full working example.
- ## schema
- The email element schema for specs. Use with `defineCatalog` from core.
- ```typescript
- import { defineCatalog } from '@json-render/core';
- import { schema, standardComponentDefinitions } from '@json-render/react-email';
- const catalog = defineCatalog(schema, {
- components: standardComponentDefinitions,
- });
- ```
- ## Render Functions
- Server-side functions for producing email output. All accept a spec and optional `RenderOptions`.
- ```typescript
- import { renderToHtml, renderToPlainText } from '@json-render/react-email';
- const html = await renderToHtml(spec);
- const plainText = await renderToPlainText(spec);
- ```
- ### RenderOptions
- ```typescript
- interface RenderOptions {
- registry?: ComponentRegistry;
- includeStandard?: boolean; // default: true
- state?: Record<string, unknown>;
- }
- ```
- <table>
- <thead>
- <tr>
- <th>Option</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>registry</code></td>
- <td>Custom component map (merged with standard components)</td>
- </tr>
- <tr>
- <td><code>includeStandard</code></td>
- <td>Include built-in standard components (default: <code>true</code>)</td>
- </tr>
- <tr>
- <td><code>state</code></td>
- <td>Initial state for <code>$state</code> / <code>$cond</code> dynamic prop resolution</td>
- </tr>
- </tbody>
- </table>
- ## defineRegistry
- Create a type-safe component registry from a catalog. Components receive `{ props, children, emit, bindings, loading }`.
- ```tsx
- import { defineRegistry } from '@json-render/react-email';
- import { Container, Heading, Text } from '@react-email/components';
- const { registry } = defineRegistry(catalog, {
- components: {
- Card: ({ props, children }) => (
- <Container style={{ padding: 16, backgroundColor: '#fff' }}>
- <Heading>{props.title}</Heading>
- {children}
- </Container>
- ),
- },
- });
- const html = await renderToHtml(spec, { registry });
- ```
- ## createRenderer
- Create a standalone renderer component wired to state, actions, and validation (for interactive previews in the browser).
- ```typescript
- import { createRenderer } from '@json-render/react-email';
- const EmailRenderer = createRenderer(catalog, components);
- ```
- ## Renderer
- The main component that renders a spec to React Email elements. Use inside `JSONUIProvider` when you need state, actions, or visibility.
- ```typescript
- interface RendererProps {
- spec: Spec | null;
- registry?: ComponentRegistry;
- includeStandard?: boolean; // default: true
- loading?: boolean;
- fallback?: ComponentRenderer;
- }
- ```
- ## Standard Components
- ### Document structure
- <table>
- <thead>
- <tr>
- <th>Component</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>Html</code></td>
- <td>Top-level email wrapper. Must be the root element.</td>
- </tr>
- <tr>
- <td><code>Head</code></td>
- <td>Email head section. Place inside Html.</td>
- </tr>
- <tr>
- <td><code>Body</code></td>
- <td>Email body wrapper. Place inside Html.</td>
- </tr>
- </tbody>
- </table>
- ### Layout
- <table>
- <thead>
- <tr>
- <th>Component</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>Container</code></td>
- <td>Constrains content width (e.g. max-width 600px).</td>
- </tr>
- <tr>
- <td><code>Section</code></td>
- <td>Groups related content.</td>
- </tr>
- <tr>
- <td><code>Row</code></td>
- <td>Horizontal layout row.</td>
- </tr>
- <tr>
- <td><code>Column</code></td>
- <td>Column within a Row.</td>
- </tr>
- </tbody>
- </table>
- ### Content
- <table>
- <thead>
- <tr>
- <th>Component</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>Heading</code></td>
- <td>Heading text (h1-h6).</td>
- </tr>
- <tr>
- <td><code>Text</code></td>
- <td>Body text paragraph.</td>
- </tr>
- <tr>
- <td><code>Link</code></td>
- <td>Hyperlink with text and href.</td>
- </tr>
- <tr>
- <td><code>Button</code></td>
- <td>Call-to-action button (link styled as button).</td>
- </tr>
- <tr>
- <td><code>Image</code></td>
- <td>Image from URL.</td>
- </tr>
- <tr>
- <td><code>Hr</code></td>
- <td>Horizontal rule separator.</td>
- </tr>
- </tbody>
- </table>
- ### Utility
- <table>
- <thead>
- <tr>
- <th>Component</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>Preview</code></td>
- <td>Preview text for inbox (inside Html).</td>
- </tr>
- <tr>
- <td><code>Markdown</code></td>
- <td>Renders markdown content as email-safe HTML.</td>
- </tr>
- </tbody>
- </table>
- ## Server-Safe Import
- Import schema and catalog definitions without pulling in React or `@react-email/components`:
- ```typescript
- import { schema, standardComponentDefinitions } from '@json-render/react-email/server';
- ```
- ## Sub-path Exports
- <table>
- <thead>
- <tr>
- <th>Export</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>@json-render/react-email</code></td>
- <td>Full package: schema, renderer, components, render functions</td>
- </tr>
- <tr>
- <td><code>@json-render/react-email/server</code></td>
- <td>Schema and catalog definitions only (no React)</td>
- </tr>
- <tr>
- <td><code>@json-render/react-email/catalog</code></td>
- <td>Standard component definitions and types</td>
- </tr>
- <tr>
- <td><code>@json-render/react-email/render</code></td>
- <td>Server-side render functions only</td>
- </tr>
- </tbody>
- </table>
- ## Types
- <table>
- <thead>
- <tr>
- <th>Export</th>
- <th>Description</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td><code>ReactEmailSchema</code></td>
- <td>Schema type for email specs</td>
- </tr>
- <tr>
- <td><code>ReactEmailSpec</code></td>
- <td>Spec type for email documents</td>
- </tr>
- <tr>
- <td><code>RenderOptions</code></td>
- <td>Options for render functions</td>
- </tr>
- <tr>
- <td><code>ComponentContext</code></td>
- <td>Typed component render function context</td>
- </tr>
- <tr>
- <td><code>ComponentFn</code></td>
- <td>Component render function type</td>
- </tr>
- <tr>
- <td><code>StandardComponentDefinitions</code></td>
- <td>Type of the standard component definitions object</td>
- </tr>
- <tr>
- <td><code>StandardComponentProps<K></code></td>
- <td>Inferred props type for a standard component by name</td>
- </tr>
- </tbody>
- </table>
|