Set up a mail server once, then send from any server code with mail(). Sign-in links, invitations, password resets and notifications use the same one.
Setting it up
In the admin UI, under Mail:
| Host and port | Your provider’s SMTP server: smtp.example.com, 587 |
| Username, password | The password is kept on the server and never sent back out |
| From, from name | The address mail comes from, and the name beside it: “Springfield Elementary” rather than a bare address |
| Base URL | Where links in mail point. Without one, the address the app is served at |
| TLS | STARTTLS, on unless a local relay doesn’t speak it |
Without a host, mail is off. That is a fine way to run: nothing fails, nothing is sent.
Sending
export async function act({ event, mail, link }) {
const sent = await mail({
to: event.data.email,
subject: "Paid, thank you",
text: `Your order is paid. See it at ${await link("/orders")}`,
});
}mail({ to, subject, text })answers whether it went:falsewhen mail isn’t set up or the server refused, which is logged, never thrown.link(path)makes a path in the app into a full address for a letter, from the base URL.
Mail is plain text on purpose. A notification says there is something in the app and links to it; it doesn’t try to be the conversation, so nobody replies to an address that nobody reads.
What Sluurp sends by itself
Sign-in links, password resets and invitations, in the app’s language. Threads in conversations mail the people who weren’t there when a message arrived; chat rooms never do, so the mail stays worth reading.