Usage
Test Your Setup
Start your Nuxt development server:
npm run dev
yarn dev
pnpm dev
bun run dev
WelcomeEmail template listed.Rendering Emails in Server-Side Code
You can use the renderEmailComponent function in your server-side code to render email templates. This is the recommended approach for rendering emails in production.
Here's an example of how to use it in a server route:
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const html = await renderEmailComponent(body.name, body.props, {
pretty: true,
});
// You can now use the rendered HTML (e.g., send it via email)
// Example: await sendEmail({ to: body.email, html })
return { success: true };
});
Creating a Custom API Endpoint
If you need to render emails from client-side code, you should create your own API endpoint. This gives you full control over authentication, authorization, and which templates can be rendered.
Here's an example:
import { z } from "zod";
// Define which templates are allowed to be rendered from the client
const ALLOWED_TEMPLATES = ["WelcomeEmail", "PasswordResetEmail"];
const bodySchema = z.object({
name: z.string().refine((name) => ALLOWED_TEMPLATES.includes(name), {
message: "Invalid template name",
}),
props: z.record(z.any()).optional(),
});
export default defineEventHandler(async (event) => {
// Add your own authentication/authorization logic here
// const user = await requireUser(event)
const { name, props } = await readValidatedBody(event, bodySchema.parse);
const html = await renderEmailComponent(name, props, {
pretty: true,
});
return html;
});
Then you can call it from your client-side code:
const html = await $fetch("/api/render-email", {
method: "POST",
body: {
name: "WelcomeEmail",
props: {
userName: "John Doe",
confirmationUrl: "https://example.com/confirm?token=abc123",
},
},
});
Dynamic DevTools Preview Props (Hook)
You can inject dynamic props into the DevTools preview render endpoint (/api/emails/render) with a Nitro runtime hook.
Because email rendering happens on the server, register this hook in a server plugin (server/plugins/*), not a client plugin.
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook("nuxt-email-renderer:devtools:resolveProps", (context) => {
if (context.templateName !== "AwsVerifyEmail") {
return
}
// Full props object is available and can be replaced/extended.
context.props = {
...context.props,
verificationCode: "123456",
}
})
})
context.templateName is normalized (without .vue) and context.props is the full object passed to the template renderer.