nuxt-mailkite
v0.1.0
Published
MailKite for Nuxt — receive inbound email as a signed webhook route in your Nuxt app, and send over your verified domain.
Maintainers
Readme
What it does
The module registers a POST /api/mailkite/inbound endpoint in your Nuxt app. When mail arrives
at any address on your verified domain, MailKite POSTs a signed email.received event there; the
module verifies the x-mailkite-signature header (HMAC-SHA256, no network call) and hands the
event to your handler module — server/mailkite.ts by default. It also gives every nitro route
useMailKite() (the mailkite SDK client as a
singleton) and the webhook reply helpers as auto-imports, so an auto-reply bot is a one-file affair.
Install
npx nuxt module add mailkiteOr manually:
npm install nuxt-mailkite// nuxt.config.ts
export default defineNuxtConfig({
modules: ['nuxt-mailkite'],
})Set your secrets in .env (standard Nuxt runtime-config env mapping):
NUXT_MAILKITE_API_KEY=mk_… # for sending
NUXT_MAILKITE_WEBHOOK_SECRET=whsec_… # for receivingReceive email — an auto-reply bot in one file
Create server/mailkite.ts; its default export handles every verified inbound email
(useMailKite() and the reply helpers are nitro auto-imports — no import needed):
// server/mailkite.ts
import type { MailKiteInboundHandler } from 'nuxt-mailkite'
const handler: MailKiteInboundHandler = async (event) => {
const m = event.message
if (event.type !== 'email.received' || !m) return replyOk()
await useMailKite().send({
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 handlerPoint your MailKite domain webhook at https://your-site.com/api/mailkite/inbound
(dashboard → domain → Webhooks, or mk.setWebhook(...) from the mailkite SDK).
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 |
No server/mailkite.ts yet? Deliveries are still verified, logged, and acknowledged — nothing is lost.
Send email
useMailKite() returns the mailkite SDK client,
authenticated with NUXT_MAILKITE_API_KEY. Use it in any server route, nitro task, or the
inbound handler:
// server/api/invoice.post.ts
export default defineEventHandler(async () => {
const { id, status } = await useMailKite().send({
from: '[email protected]',
to: '[email protected]',
subject: 'Your invoice #1042',
html: '<p>Thanks! Receipt attached.</p>',
})
return { id, status }
})The full SDK surface (domains, templates, routes, broadcasts…) is on the same client —
see the mailkite docs.
Environment variables
| Variable | Runtime config | Used by | Required | Where to get it |
| --- | --- | --- | --- | --- |
| NUXT_MAILKITE_WEBHOOK_SECRET | mailkite.webhookSecret | inbound endpoint (signature verification) | for receiving | dashboard → Webhooks |
| NUXT_MAILKITE_API_KEY | mailkite.apiKey | useMailKite() | for sending | dashboard → API keys |
You can also set them in nuxt.config.ts under runtimeConfig.mailkite — the env vars
override at runtime (standard Nuxt behavior). They are server-only and never reach the client bundle.
Options
export default defineNuxtConfig({
modules: ['nuxt-mailkite'],
mailkite: {
inboundPath: '/api/mailkite/inbound', // route for the registered endpoint
handler: 'server/mailkite.ts', // module whose default export handles inbound email
},
})| Option | Default | Notes |
| --- | --- | --- |
| inboundPath | /api/mailkite/inbound | Registered as a POST-only nitro route. |
| handler | server/mailkite.ts | Also probes .js/.mts/.mjs. An explicitly set path that doesn't exist fails the build. |
Notes
- Runtimes: works on the node, Vercel, and Cloudflare nitro presets. The SDK's
verifyWebhookusesnode:crypto— on Cloudflare, nitro'snodejs_compatcovers it. - DevTools: the module shows up in Nuxt DevTools (Modules tab), and the inbound route is visible under Server Routes.
License
MIT © MailKite
