Mailer
Sending transactional emails (like password resets, welcome messages, or invoices) is a common requirement. Harpia’s application boilerplate comes pre-configured with a clean Mailer service abstraction, ensuring a robust and strongly-typed approach to email delivery out of the box.
Configuration
Your email provider credentials should be stored securely in your .env file:
SMTP_HOST=smtp.mailtrap.io
SMTP_PORT=2525
SMTP_SECURE=false
SMTP_USER=your_username
SMTP_PASSWORD=your_password
Harpia safely ingests these variables and maps them into the strongly-typed MailerConfigInterface located at app/config/mailer.ts. If you ever need to change SMTP options or swap to an external API-based provider (like Resend or Sendgrid), you should update this configuration file.
The Mailer Service
The boilerplate provides an abstracted, ready-to-use Mailer class in app/services/mailer/index.ts. This static class uses the nodemailer transporter under the hood.
To dispatch an email, simply import the class and invoke the sendMail() method anywhere in your application (for example, inside an Observer or a Service).
// app/observers/user.observer.ts
import { Observer } from "app/observers";
import Mailer from "app/services/mailer";
Observer.model("User", "create", async ({ data }) => {
await Mailer.sendMail({
from: "Harpia App <noreply@harpiats.dev>",
to: data.email,
subject: "Welcome to Harpia!",
html: `<h1>Hello ${data.name}</h1><p>We're thrilled to have you on board.</p>`,
});
});
The method arguments are strictly typed via the SendMailTypes interface provided by @harpiats/common, ensuring autocompletion and safety.
Using HTML Templates
Whilst you can write raw HTML strings directly in your code, it is highly recommended to use a template engine for more complex, maintainable email layouts.
Harpia’s Template Engine
Harpia features a powerful, built-in Template Engine. You can compile dynamic .html files into raw HTML strings and inject them straight into the mailer payload by using the engine.generate() method.
Assume you have a view file at app/services/mailer/templates/welcome.html:
<!-- welcome.html -->
<h1>Hello, {{ user.name }}!</h1>
<p>Your account was successfully created.</p>
You can render and send it like so:
import Mailer from "app/services/mailer";
import { app } from "start/server";
export const sendWelcomeEmail = async (user) => {
const engine = app.engine.get();
// Compiles the template into a raw HTML string, injecting the variables
const htmlContent = await engine.generate("emails/welcome", { user });
await Mailer.sendMail({
from: "Harpia App <noreply@harpiats.dev>",
to: user.email,
subject: "Welcome aboard!",
html: htmlContent,
});
};
Third-Party Template Engines
If you prefer different syntaxes, you are not locked into Harpia’s native engine. You can easily plug in third-party rendering engines like Pug, EJS, or Handlebars.
Simply compile the template into an HTML string using your chosen library’s renderer, and pass the resulting string to the html property of Mailer.sendMail().