EmailMail MessagesBuilding Messages

Building Messages

Learn how to build email messages using the fluent API

Last updated:

Building Messages

The MailMessage class provides a fluent, chainable API for building email messages. This guide covers all available methods.

Basic Message

import { createMail, MailMessage } from "@visulima/email";
import { resendProvider } from "@visulima/email/providers/resend";

const mail = createMail(resendProvider({ apiKey: "re_xxx" }));

const message = new MailMessage().to("user@example.com").from("sender@example.com").subject("Hello").html("<h1>Hello World</h1>");

const result = await mail.send(message);

Setting Recipients

To Addresses

// Single recipient (string)
new MailMessage().to("user@example.com");

// Single recipient (object)
new MailMessage().to({ email: "user@example.com", name: "John Doe" });

// Multiple recipients (array)
new MailMessage().to(["user1@example.com", "user2@example.com"]);

// Multiple recipients (array of objects)
new MailMessage().to([
    { email: "user1@example.com", name: "User 1" },
    { email: "user2@example.com", name: "User 2" },
]);

CC and BCC

new MailMessage().to("user@example.com").cc("cc@example.com").bcc("bcc@example.com");

Reply-To

new MailMessage().to("user@example.com").from("sender@example.com").replyTo("reply@example.com");

Setting Content

Subject

new MailMessage().subject("Welcome to our service!");

HTML Content

new MailMessage().html("<h1>Hello</h1><p>This is HTML content.</p>");

Plain Text Content

new MailMessage().text("Hello\n\nThis is plain text content.");

Both HTML and Text

new MailMessage().html("<h1>Hello</h1><p>This is HTML.</p>").text("Hello\n\nThis is plain text.");

Custom Headers

new MailMessage().header("X-Custom-Header", "value").header("X-Priority", "1");

Or set multiple headers at once:

new MailMessage().setHeaders({
    "X-Custom-Header": "value",
    "X-Priority": "1",
    "X-Mailer": "MyApp",
});

Attachments

Attach File from Path

await message.attachFromPath("/path/to/file.pdf");

With options:

await message.attachFromPath("/path/to/file.pdf", {
    filename: "custom-name.pdf",
    contentType: "application/pdf",
});

Attach Data

message.attachData(Buffer.from("file content"), {
    filename: "document.txt",
    contentType: "text/plain",
});

Inline Attachments

Embed Image from Path

const cid = await message.embedFromPath("/path/to/image.png");
// Use cid in HTML: <img src="cid:${cid}" />

Embed Image Data

const cid = message.embedData(Buffer.from("image data"), "logo.png", {
    contentType: "image/png",
});
// Use cid in HTML: <img src="cid:${cid}" />

Using Templates

Handlebars Template

import { renderHandlebars } from "@visulima/email/template/handlebars";

await message.view(renderHandlebars, "<h1>Hello {{name}}!</h1>", { name: "John" });

MJML Template

import mjml from "@visulima/email/template/mjml";

const mjmlTemplate = `
<mjml>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-text>Hello World</mj-text>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>
`;

await message.view(mjml, mjmlTemplate);

React Email

import reactEmail from "@visulima/email/template/react-email";
import { WelcomeEmail } from "./emails/WelcomeEmail";

await message.view(reactEmail, <WelcomeEmail name="John" />);

Vue Email

import vueEmail from "@visulima/email/template/vue-email";
import { MyTemplate } from "./emails/MyTemplate";

// Render HTML
await message.view(
    vueEmail,
    MyTemplate,
    {
        title: "some title",
    },
    {
        pretty: true,
    },
);

// Render plain text
await message.view(
    vueEmail,
    MyTemplate,
    {
        title: "some title",
    },
    {
        plainText: true,
    },
);

Auto-Generate Text from HTML

When using templates, text can be automatically generated from HTML:

import { renderHandlebars } from "@visulima/email/template/handlebars";

await message.view(
    renderHandlebars,
    "<h1>Hello {{name}}!</h1><p>Welcome to our service.</p>",
    { name: "John" },
    { autoText: true }, // Default: true
);

Building Without Sending

You can build the email options without sending:

const emailOptions = await message.build();
// Use emailOptions with another provider or for testing

Complete Example

import { createMail, MailMessage } from "@visulima/email";
import { resendProvider } from "@visulima/email/providers/resend";
import { renderHandlebars } from "@visulima/email/template/handlebars";

const mail = createMail(resendProvider({ apiKey: "re_xxx" }));

const message = new MailMessage()
    .to({ email: "user@example.com", name: "John Doe" })
    .cc("cc@example.com")
    .from({ email: "sender@example.com", name: "My App" })
    .replyTo("support@example.com")
    .subject("Welcome!")
    .header("X-Priority", "1");

await message.view(renderHandlebars, "<h1>Hello {{name}}!</h1>", { name: "John" });
await message.attachFromPath("/path/to/welcome.pdf");

const result = await mail.send(message);

Next Steps

Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues