Email

Email Templates

Build responsive, localized email templates with React Email and VitNode default layouts.

VitNode renders email templates using React Email. Templates are standard React components transformed into cross-client compatible HTML tables with localized text and inline styles.

Quick start

1. Build the Template Component

Wrap template content inside DefaultTemplateEmail:

plugins/blog/src/emails/welcome-email.tsx
import DefaultTemplateEmail, {
  type DefaultTemplateEmailProps,
} from "@vitnode/core/emails/default-template"
import { Button, Section, Text } from "react-email"

interface WelcomeEmailProps extends DefaultTemplateEmailProps {
  loginUrl?: string
}

export default function WelcomeEmail({
  user,
  loginUrl = "https://example.com/login",
  ...props
}: WelcomeEmailProps) {
  return (
    <DefaultTemplateEmail user={user} {...props}>
      <Section className="p-4 text-center">
        <Text className="text-xl font-bold">Welcome, {user.name}!</Text>
        <Text className="text-muted-foreground">
          We are thrilled to have you in the community.
        </Text>
        <Button href={loginUrl} className="bg-primary text-primary-foreground px-4 py-2 rounded-md">
          Visit Your Account
        </Button>
      </Section>
    </DefaultTemplateEmail>
  )
}

2. Send the Email

Send or queue the email from any Hono route or task:

import WelcomeEmail from "@/emails/welcome-email"

await c.get("email").send({
  user: { email: user.email, name: user.name },
  subject: "Welcome to VitNode!",
  content: WelcomeEmail,
})

send() handles locale resolution, renders the JSX to HTML, and pushes the delivery to the mail transport.


Preview Templates Locally

Preview emails in your browser during development using the React Email preview server:

Start email dev server
bun run email dev
pnpm exec email dev
npx email dev

Visit http://localhost:3001 to view your email rendered live with hot reloading.


Localization in Emails

Email templates receive the recipient's preferred locale automatically:

export default function OrderEmail({ i18n, ...props }: DefaultTemplateEmailProps) {
  return (
    <DefaultTemplateEmail i18n={i18n} {...props}>
      <Text>{i18n.t("order.confirmed")}</Text>
    </DefaultTemplateEmail>
  )
}

Learn More