Skip to main content

Render from Nitro

Call the typed, server-only renderEmail auto-import and pass its html and text to your provider SDK.

renderEmail(name, props) is the one public application rendering path. It is a Nitro-only auto-import generated from app/emails/ — available in server handlers and other Nitro server code, never in Vue components, client plugins, or client bundles.

Call it from a handler

server/api/welcome.get.ts
export default defineEventHandler(async () => {
  const { html, text } = await renderEmail('welcome', {
    firstName: 'Ada',
    activationUrl: 'https://example.com/activate',
  })

  // Hand html + text to your provider SDK — Nuxt Email does not send mail.
  return { html, text }
})

Do not import renderEmail from @lupinum/nuxt-email or #imports; it is injected as a server auto-import. TypeScript checks the template name 'welcome' and its exact props.

The result shape

The promise resolves to RenderedEmail, which is available as a type-only root import when you need to annotate application code:

ts
import type { RenderedEmail } from '@lupinum/nuxt-email'
  • html begins with the XHTML 1.0 Transitional doctype and is deterministic.
  • text is a plain-text fallback derived from the final HTML.
  • subject is present only when the template declares one via defineEmail.

Nuxt Email owns the body content. Recipients, sender identity, credentials, attachments, and delivery stay in your provider SDK. See the renderEmail reference for the full contract.

Generate and verify types

The generated server declarations change when templates are added, renamed, or deleted:

bash
pnpm exec nuxt prepare
pnpm exec vue-tsc --noEmit -p .nuxt/tsconfig.server.json

If an editor was open before nuxt prepare, restart its TypeScript service once so it reloads the generated server config.

Preview while you build

Run pnpm exec nuxt dev and open /__email to inspect the preview, exact HTML, and plain text for any template with a fixture. See the preview workflow.