mail

Write emails as React components, send them through your provider, and preview them in development.

BackendServerBuilt onReact Email

Every export of kitr/mail, kitr/mail/provider, read from the published type definitions. The guide shows them in use.

kitr/mail

address

function address(input: Recipient): Address;

createLogTransport

function createLogTransport(options?: {
  print?: boolean;
}): MailTransport & {
  messages: Message[];
};

Keeps messages in memory and prints them; the default outside production.

createMailer

function createMailer(options?: CreateMailerOptions): Mailer;

createResendTransport

function createResendTransport(options: {
  apiKey: string;
  fetch?: typeof fetch;
}): MailTransport;

Resend's HTTP API.

createSmtpTransport

function createSmtpTransport(nodemailer: NodemailerLike | {
  default: NodemailerLike;
}, options: {
  host: string;
  port?: number;
  secure?: boolean;
  auth?: {
    user: string;
    pass: string;
  };
}): MailTransport;

SMTP through nodemailer (pnpm add nodemailer). Pass the module in so the bundler sees a real dependency: createSmtpTransport(nodemailer, { host, port, auth }).

defineMail

function defineMail<Props = Record<string, never>>(name: string, template: Omit<MailTemplate<Props>, 'name'>): MailTemplate<Props>;

formatAddress

function formatAddress(a: Address): string;

htmlToText

function htmlToText(html: string): string;

A readable text version of an HTML body.

mailPreview

function mailPreview<S extends {
  h3: {
    get(path: string, handler: (event: any) => unknown): unknown;
  };
}>(server: S, templates: MailTemplate<any>[], options?: {
  path?: string;
  mailer?: Mailer;
}): S;

Serves every registered template at <previewPath>/<name> in development (the preview props, or ?prop=value from the query string), and an index listing them.

useMailer

function useMailer(app: KitrApp): Mailer;

defineConfig

const defineConfig: <const C extends MailConfig>(config: C) => C;

Address

interface Address {
  email: string;
  name?: string;
}

CreateMailerOptions

interface CreateMailerOptions extends MailConfig {
  /** Renders React to static HTML. Default: react-dom/server's renderToStaticMarkup. */
  renderHtml?: (element: ReactElement) => Promise<string> | string;
}

MailConfig

interface MailConfig {
  transport?: MailTransport;
  /** Default sender. */
  from?: Recipient;
  /** Serve rendered templates at this path in development. Default `/_kitr/mail`; false disables. */
  previewPath?: string | false;
}

Mailer

interface Mailer {
  send<P>(template: MailTemplate<P>, props: P, options: SendOptions): Promise<SentMail>;
  /** The rendered message without sending it, for tests and previews. */
  render<P>(template: MailTemplate<P>, props: P, options?: Partial<SendOptions>): Promise<Message>;
  readonly transport: MailTransport;
  /** Messages the log transport kept, newest last. Empty with other transports. */
  readonly sent: readonly Message[];
}

MailTemplate

interface MailTemplate<Props> {
  name: string;
  subject: string | ((props: Props) => string);
  /** The body as React. Plain components, or React Email's <Html>, <Button> and friends. */
  render: (props: Props) => ReactElement;
  /** A text alternative; derived from the HTML when left out. */
  text?: (props: Props) => string;
  /** Props the development preview renders with. */
  preview?: Props;
}

MailTransport

interface MailTransport {
  name: string;
  send(message: Message): Promise<{
    id?: string;
  }>;
}

Where messages go.

Message

interface Message {
  from: Address;
  to: Address[];
  cc?: Address[];
  bcc?: Address[];
  replyTo?: Address;
  subject: string;
  html: string;
  text: string;
  headers?: Record<string, string>;
  attachments?: Array<{
    filename: string;
    content: string | Uint8Array;
    contentType?: string;
  }>;
}

NodemailerLike

interface NodemailerLike {
  createTransport(options: unknown): {
    sendMail(message: Record<string, unknown>): Promise<{
      messageId?: string;
    }>;
  };
}

The part of nodemailer the SMTP transport uses; pass the module itself.

SendOptions

interface SendOptions {
  to: Recipient | Recipient[];
  cc?: Recipient | Recipient[];
  bcc?: Recipient | Recipient[];
  from?: Recipient;
  replyTo?: Recipient;
  headers?: Record<string, string>;
  attachments?: Message['attachments'];
}

SentMail

interface SentMail {
  id: string;
  transport: string;
}

Recipient

type Recipient = string | Address;

kitr/mail/provider

mailProvider

const mailProvider: import("@kitr/core").KitrProvider;

Binds mailer from config/mail.ts; the log transport outside production unless one is set.