Skip to main content

Email Templates Reference

The Ever Works platform uses Handlebars (.hbs) templates for all transactional emails. These templates live in apps/api/src/templates/ and are rendered by the MailService using the @nestjs/event-emitter event system.

Architecture Overview

User Action (e.g., signup)
--> AuthService emits event (e.g., UserCreatedEvent)
--> MailService listens via @OnEvent decorator
--> MailerService renders .hbs template with context
--> Email sent via configured provider (SMTP / Resend)

All templates share a consistent design system with a branded header, main content card, and footer section. They use the system font stack (-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif) and a #f8fafc background color.

Template Inventory

Template FileEvent ClassEvent NameTrigger
signup-confirmation.hbsUserCreatedEventuser.createdUser registers a new account
forgot-password.hbsUserForgotPasswordEventuser.forgot_passwordUser requests password reset
password-changed.hbsUserPasswordChangedEventuser.password_changedUser successfully changes password
welcome.hbsUserConfirmedEventuser.confirmedUser confirms email address
new-device-login.hbsUserNewDeviceLoginEventuser.new_device_loginLogin detected from new device
account-deletion.hbsUserAccountDeletionEventuser.delete_accountUser requests account deletion
member-invitation.hbsMemberInvitedEventwork.member_invitedUser is invited to a work

Global Context Variables

Every template receives these branding variables from the getBrandingContext() helper in MailService:

VariableTypeDescription
appNamestringApplication name (e.g., "Ever Works")
companyOwnerstringCompany name for copyright
platformWebsitestringPlatform marketing website URL
currentYearnumberCurrent year for copyright notice

Template Details

1. Signup Confirmation (signup-confirmation.hbs)

Sent when a new user registers. Contains an email verification link.

Context Variables:

VariableTypeDescription
firstNamestringUser's display name
confirmationUrlstringEmail confirmation link
confirmationTokenstringConfirmation token value

Handlebars Usage:

<h2 class='title'>
Welcome to
{{appName}}{{#if firstName}}, {{firstName}}{{/if}}
</h2>
<a href='{{confirmationUrl}}' class='button'>
Confirm Email Address
</a>

The template includes a fallback plain-text link section for email clients that do not render buttons properly.

2. Forgot Password (forgot-password.hbs)

Sent when a user requests a password reset. Contains a time-limited reset link.

Context Variables:

VariableTypeDescription
firstNamestringUser's display name
resetUrlstringPassword reset link
resetTokenstringReset token value
expiresInstringExpiry duration (e.g., "1 hour")

Handlebars Usage:

{{#if firstName}}Hi {{firstName}}, we{{else}}We{{/if}}
received a request to reset the password for your
{{appName}}
account.

3. Password Changed (password-changed.hbs)

Security notification sent after a successful password change. Includes device and location details.

Context Variables:

VariableTypeDescription
firstNamestringUser's display name
changedAtstringFormatted date/time of change
ipAddressstringIP address of the requester
locationstringGeographic location
devicestringDevice description
browserstring (optional)Browser name
secureAccountUrlstringLink to secure the account

Conditional Rendering:

<strong>Device:</strong>
{{device}}{{#if browser}}<br />
<strong>Browser:</strong>
{{browser}}{{/if}}

4. Welcome (welcome.hbs)

Sent after a user confirms their email. Includes onboarding steps and a CTA to the dashboard.

Context Variables:

VariableTypeDescription
firstNamestringUser's display name
dashboardUrlstringLink to create first work

The template displays a three-step getting-started guide:

  1. Create your first work
  2. Generate with AI
  3. Deploy your work

5. New Device Login (new-device-login.hbs)

Security alert sent when a login is detected from a previously unseen device.

Context Variables:

VariableTypeDescription
firstNamestringUser's display name
loginTimestringFormatted login timestamp
devicestringDevice name/type
browserstringBrowser name
locationstringGeographic location
ipAddressstringIP address
verifyUrlstring"Yes, this was me" link
verifyTokenstringVerification token
secureAccountUrlstring"No, secure my account" link

This template uses two CTA buttons: a primary "Yes, this was me" button and a danger-styled "No, secure my account" button.

6. Account Deletion (account-deletion.hbs)

Sent when a user requests account deletion. Requires explicit confirmation before proceeding.

Context Variables:

VariableTypeDescription
firstNamestringUser's display name
deleteUrlstringConfirm deletion link
deleteTokenstringDeletion confirmation token
keepAccountUrlstringCancel deletion link
expiresInstringExpiry duration (e.g., "24 hours")

The template includes a prominent warning box listing what will be permanently deleted:

  • All projects and data
  • Profile and settings
  • Access to platform services

7. Member Invitation (member-invitation.hbs)

Sent when a user is invited to collaborate on a work.

Context Variables:

VariableTypeDescription
inviteeNamestringInvited user's name
inviterNamestringName of the person inviting
workNamestringName of the work
roleNamestringAssigned role (formatted)
workUrlstringLink to the work

The template displays an info box with a table layout showing work name, assigned role (with a styled badge), and inviter name.

Handlebars Patterns Used

Conditional Greetings

All user-facing templates use a consistent pattern for optional personalization:

{{#if firstName}}{{firstName}}, your{{else}}Your{{/if}}

Every template ends with:

© {{currentYear}} {{companyOwner}} All rights reserved.

Customizing Templates

To customize email templates:

  1. Edit the .hbs file in apps/api/src/templates/
  2. Maintain all existing context variables (removing a used variable will show undefined)
  3. Keep the responsive layout (max-width: 600px container)
  4. Use inline CSS styles (many email clients strip <style> tags from the body)
  5. Test with tools like Litmus or Email on Acid for client compatibility

Adding a New Template

  1. Create a new .hbs file in the templates work
  2. Define a new event class in apps/api/src/events/index.ts
  3. Add an @OnEvent handler in MailService
  4. Emit the event from the relevant service using EventEmitter2
// 1. Define the event
export class MyCustomEvent extends BaseUserEvent {
static EVENT_NAME = 'user.custom_action';
constructor(public user: User, public customUrl: string) {
super();
}
}

// 2. Handle in MailService
@OnEvent(MyCustomEvent.EVENT_NAME)
async sendCustomEmail(data: MyCustomEvent): Promise<void> {
await this.mailerService.sendMail({
to: data.user.email,
subject: 'Custom Subject',
template: 'my-custom-template',
context: {
...this.getBrandingContext(),
firstName: data.user.username,
customUrl: data.customUrl,
},
});
}

Email Provider Configuration

Templates are rendered and sent through the MailerService, which supports:

ProviderEnvironment Variables
SMTPSMTP_HOST, SMTP_PORT, SMTP_SECURE, SMTP_USER, SMTP_PASSWORD
ResendRESEND_APIKEY, RESEND_EMAIL_FROM

The active provider is selected via MAILER_PROVIDER and the sender address via EMAIL_FROM.

Source Files

FilePurpose
apps/api/src/templates/*.hbsHandlebars email templates
apps/api/src/mail/mail.service.tsEvent listeners and template rendering
apps/api/src/events/index.tsEvent class definitions
apps/api/src/mail/providers/mailer.service.tsMail transport abstraction