Templates

Template for email messages

This documentation is under construction! 🚧

We're working hard to bring you the best documentation experience.

VitNode uses React Email to create email templates. This allows us to create responsive and customizable email templates that can be used in various applications with React components.

Preview Server

To preview your email templates, you can run the preview server. This server will render your email templates and allow you to see how they look in a browser with fast refresh capabilities.

Email Preview Server
bun dev:email
pnpm dev:email
npm run dev:email

Usage

Inside your:

  • plugin directory => plugins/{your_plugin}/src/emails/,
  • or in the directory of your application => src/emails/

you can create your email templates. The templates should be React components that return JSX and to be exported as default.

src/emails/test-template.tsx
import { Text } from '@react-email/components';
import DefaultTemplateEmail, {
  type DefaultTemplateEmailProps,
} from '@vitnode/core/emails/default-template';

export default function TestTemplateEmail(props: DefaultTemplateEmailProps) {
  return (
    <DefaultTemplateEmail {...props}>
      <Text>This is a test email template.</Text>
    </DefaultTemplateEmail>
  );
}

TestTemplateEmail.PreviewProps =
  DefaultTemplateEmail.PreviewProps satisfies DefaultTemplateEmailProps;
src/api/modules/users/routes/test.route.ts
import { z } from 'zod';
import { buildRoute } from '@vitnode/core/api/lib/route';
import { UserModel } from '@vitnode/core/api/models/user';

import TestTemplateEmail from '@/emails/test-template';

export const testRoute = buildRoute({
  handler: async c => {
    const user = await new UserModel().getUserById({
      id: 3,
      c,
    });

    if (!user) throw new Error('User not found');

    await c.get('email').send({
      subject: 'Test Email',
      content: TestTemplateEmail,
      user,
    });

    return c.text('test');
  },
});

Preview

Here is how DefaultTemplateEmail component looks like in the preview server:

Default Template Preview

Of course, you can customize the DefaultTemplateEmail component to fit your needs like for example changing the logo, colors etc.

The DefaultTemplateEmail component is a wrapper around your email content that provides a consistent layout and styling.

TailwindCSS

We implemented TailwindCSS in the email templates to allow you to use utility classes for styling. You can use Tailwind classes directly in your email components.

TailwindCSS v4 is not yet supported!

The current TailwindCSS version used is 3.4.10.

Components

Internationalization (I18n)

VitNode supports internationalization (I18n) in email templates thanks to use-intl.

src/locales/@vitnode/blog/en.json
{
  "@vitnode/blog": {
    "title": "Blog"
  }
}

Read more about messages in Internationalization (I18n) - Messages Docs.

Use the createTranslator function to create a translator instance that can be used to translate messages in your email templates.

src/emails/test-template.tsx
import { Text } from '@react-email/components';
import DefaultTemplateEmail, {
  type DefaultTemplateEmailProps,
} from '@vitnode/core/emails/default-template';
import { createTranslator } from 'use-intl'; 

export default function TestTemplateEmail({
  i18n,
  ...props
}: DefaultTemplateEmailProps) {
  const t = createTranslator(i18n); 

  return (
    <DefaultTemplateEmail i18n={i18n} {...props}>
      <Text>{t('@vitnode/blog.title')}</Text>
    </DefaultTemplateEmail>
  );
}

TestTemplateEmail.PreviewProps = {
  ...DefaultTemplateEmail.PreviewProps,
  i18n: {
    ...DefaultTemplateEmail.PreviewProps.i18n,
    messages: {
      '@vitnode/blog': {
        title: 'Blog',
      },
    },
  },
} satisfies DefaultTemplateEmailProps;

Subject Translation

You can also translate the subject of the email using the createTranslator function. This allows you to have localized subjects for your emails.

src/api/modules/users/routes/test.route.ts
import { z } from 'zod';
import { createTranslator } from 'use-intl';
import { buildRoute } from '@vitnode/core/api/lib/route';
import { UserModel } from '@vitnode/core/api/models/user';

import TestTemplateEmail from '@/emails/test-template';

export const testRoute = buildRoute({
  handler: async c => {
    const user = await new UserModel().getUserById({
      id: 3,
      c,
    });

    if (!user) throw new Error('User not found');

    await c.get('email').send({
      subject: ({ i18n }) => {
        const t = createTranslator(i18n);

        return t('@vitnode/blog.title');
      },
      content: TestTemplateEmail,
      user,
    });

    return c.text('test');
  },
});

User in Email

If you pass user to the send method, it will be available in the email template as a prop. This allows you to personalize the email content based on the user data.

src/emails/test-template.tsx
import { Text } from '@react-email/components';
import DefaultTemplateEmail, {
  type DefaultTemplateEmailProps,
} from '@vitnode/core/emails/default-template';

export default function TestTemplateEmail({
  locale,
  messages,
  user, 
  ...props
}: DefaultTemplateEmailProps) {
  if (!user) return null;

  return (
    <DefaultTemplateEmail locale={locale} messages={messages} {...props}>
      <Text>This message is for {user.name}</Text>
    </DefaultTemplateEmail>
  );
}

TestTemplateEmail.PreviewProps =
  DefaultTemplateEmail.PreviewProps satisfies DefaultTemplateEmailProps;
Templates - VitNode