Write emails as React components, send them through your provider, and preview them in development.
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.