Skip to content

Email

Any SMTP provider, through two variables:

SMTP_URL=smtps://user:pass@smtp.example.com:465
EMAIL_FROM="My Store <orders@example.com>"

Sending is a logged no-op, not an error. Orders complete, invitations return their link to the inviting admin, password resets log their link, and nothing fails. That is deliberate, so a store can take orders before its email is wired up, but it is silent, and the Overview says so.

Template When
Ordered The webhook confirmed payment
Processing The admin moved the order to processing
Shipped The admin marked it shipped, with carrier and tracking
Refunded A refund settled
VerifyEmail A customer registered
ResetPassword A customer or administrator asked for a reset
AbandonedCart Recovery is on and a cart went quiet

templateForStatus in server/email.ts maps an order status to a template. Add a status and an .hbs pair and it is picked up on the next transition.

emails/<Name>/body.hbs and subject.hbs, a shared layout.hbs, and an items.hbs partial for order lines. The locals are pre-formatted display strings, built by toLocals, so a template does no arithmetic and cannot get money wrong by rounding it twice. Every link starts with PUBLIC_URL. Restyle them as HTML email allows; the language setting decides how the amounts and dates inside are written.

Settings → Email → Send a test sends one to the signed-in administrator through the configured transport and reports the SMTP response, rate-limited. Do it before opening the store.

Abandoned-cart reminders go out under your SMTP sender, and every one carries an unsubscribe link that suppresses the address. Beluga sends nothing on its own until recovery is turned on.