next-mailkite
v0.1.0
Published
MailKite for Next.js — receive inbound email as a signature-verified App Router route handler, and send over your verified domain.
Maintainers
Readme
What it does
createMailKiteRouteHandler(handler) builds the POST export for an App Router route. When mail
arrives at any address on your verified domain, MailKite POSTs a signed email.received event to
that route; the package verifies the x-mailkite-signature header (HMAC-SHA256, no network call)
and hands the parsed event to your handler function. It also exports sendEmail() and the webhook
reply helpers so an auto-reply bot is a two-file affair.
Next.js has no plugin/module system like Astro or Nuxt, so there's no auto-discovered handler file or injected route — you create the route file yourself and pass your handler in explicitly. That's the whole integration surface.
Install
npm install next-mailkiteReceive email — an auto-reply bot in two files
// lib/mailkite-handler.ts
import { sendEmail, replyOk } from 'next-mailkite';
import type { MailKiteInboundHandler } from 'next-mailkite';
const handler: MailKiteInboundHandler = async (event) => {
const m = event.message;
if (event.type !== 'email.received' || !m) return replyOk();
await sendEmail({
from: '[email protected]', // an address on your verified domain
to: m.from,
subject: `Re: ${m.subject ?? 'your email'}`,
inReplyTo: m.messageId,
text: 'Thanks — got your message. A human will follow up soon.',
});
return replyOk();
};
export default handler;// app/api/mailkite/inbound/route.ts
import { createMailKiteRouteHandler } from 'next-mailkite';
import handler from '@/lib/mailkite-handler';
export const { POST } = createMailKiteRouteHandler(handler);Point your MailKite domain webhook at https://your-app.com/api/mailkite/inbound
(dashboard → domain → Webhooks, or mk.setWebhook(...) from the mailkite SDK).
No handler yet? Call createMailKiteRouteHandler() with no arguments (or null) — deliveries are
still verified, logged, and acknowledged; nothing is dropped silently.
Your handler can return:
| Return value | Response sent to MailKite |
| --- | --- |
| undefined / void | replyOk() — acknowledge |
| a string — use replyOk(), replySpam(), replyDrop(), replyBlockSender() | sent verbatim (control-mode replies act on the message) |
| a plain object | JSON-serialized |
| a Response | returned as-is |
| a thrown error | 500 — MailKite retries the delivery |
Send email
sendEmail() is a thin wrapper over the mailkite SDK's
send() that reads MAILKITE_API_KEY from the environment. Use it anywhere server-only —
server actions, route handlers — never from a "use client" component:
// app/actions.ts
'use server';
import { sendEmail } from 'next-mailkite';
export async function sendInvoice(to: string) {
return sendEmail({
from: '[email protected]',
to,
subject: 'Your invoice #1042',
html: '<p>Thanks! Receipt attached.</p>',
});
}Need the full SDK surface (domains, templates, routes, broadcasts…)? Use mailkite directly —
it's already a dependency.
Environment variables
| Variable | Used by | Required | Where to get it |
| --- | --- | --- | --- |
| MAILKITE_WEBHOOK_SECRET | the route handler (signature verification) | for receiving | dashboard → Webhooks |
| MAILKITE_API_KEY | sendEmail() | for sending | dashboard → API keys |
Runtime notes
MailKite.verifyWebhook() uses node:crypto, so the inbound route must run on the Node.js
runtime — the App Router default. If you set export const runtime = 'edge' on the route file,
signature verification will fail to load; leave the runtime unset (or explicitly
export const runtime = 'nodejs').
API reference
| Export | What |
| --- | --- |
| createMailKiteRouteHandler(handler?, options?) | Builds { POST } for app/api/mailkite/inbound/route.ts. options.webhookSecret overrides MAILKITE_WEBHOOK_SECRET. |
| handleInbound(request, handler, options?) | The underlying verify → parse → dispatch logic, directly testable without a Next.js runtime. |
| sendEmail(message, options?) | Send over a verified domain. options.apiKey/options.baseUrl override the environment. |
| replyOk() / replySpam() / replyDrop() / replyBlockSender() | Control-mode webhook replies. |
| MailKiteInboundEvent, MailKiteInboundMessage, MailKiteInboundHandler, MailKiteHandlerResult | Types for handler authors. |
License
MIT © MailKite
