Skip to content

Emails

Your site sends a few emails by itself: the contact form messages to you, and short welcome or thank-you emails to your visitors. All of them go through Resend with the same two settings, and all their texts are in the content editor.

Email Sent to When Templates
Contact or quote message You (the Email in Site settings) A visitor sends the contact form All
Newsletter welcome The new subscriber A new address joins the newsletter (or a volunteer list that uses it) All except Aurora
Waitlist welcome The new sign-up A new address joins the waitlist Aurora
Beta welcome The new tester A new address joins the beta Swell
Interest email The new sign-up A new address registers interest in new homes Tiny Town
After a payment The buyer (the email they typed in Stripe Checkout) Stripe reports the payment to your webhook (checkout.session.completed) All

The interest lists of Bloom, Fold, Hush, Lantern, Putty, Razor and Tuck send no email.

The email after a payment has a different name and text in each template:

Template Email after a payment File
Aurora Purchase welcome, with the plan’s name src/emails/purchase-welcome.ts
Swell Pro welcome: how to unlock the plan in the app src/emails/pro-welcome.ts
Junction Tickets, with the journey src/emails/tickets.ts
Stroll Ticket, with the walk and the meeting point src/emails/ticket.ts
Stride Entry, with the race and where to pick up the bib src/emails/entry.ts
Tiny Town Pass src/emails/pass.ts
Bloom, Fold, Hush, Lantern, Putty, Quest, Razor, Tuck Purchase src/emails/purchase.ts
All others Payment (a thank-you) src/emails/payment.ts

The newsletter welcome is src/emails/newsletter-welcome.ts; Aurora’s waitlist email waitlist-welcome.ts, Swell’s beta-welcome.ts, Tiny Town’s interest.ts.

Terminal window
RESEND_API_KEY=re_...
EMAIL_FROM="Your Business <hello@example.com>"

Both are explained step by step in Contact form: a Resend account, a verified domain, an API key, and a sender on that domain. Add the same two on Vercel and redeploy.

Welcome and payment emails are sent from EMAIL_FROM, so replies go to that address: use an inbox you read. Contact messages are the exception: they have the visitor as reply-to.

Without RESEND_API_KEY no email is sent. The terminal running npm run dev (online: the Vercel logs) prints one line per email with the recipient and subject:

[email] to ana@example.com: Welcome to Sorted

In the content editor, open Interface texts → Emails. Each email has its own group with:

  • Subject
  • Heading
  • Text: one paragraph of plain text (no HTML, no Markdown; it’s escaped)
  • Button label
  • Signature

The contact message has only a Subject; the message itself is the visitor’s.

Placeholders in curly braces are filled in when the email is sent. {name} is always your site’s name (from Site settings). Payment emails add their own, such as the item, plan, walk or race that was bought: keep the placeholders that appear in the template’s default text. The full list for an email is in its file in src/emails/ (the line starting with const v =).

With several languages, emails use the texts of your default language.

Each email’s button goes to a fixed page of your site (the journal, the visit page, the prices page…), set in its file in src/emails/ (the line starting with const href =).

The address in front of it is your site’s address from astro.config.mjs:

const site = 'https://example.com';

All emails except the contact message share one layout, src/emails/layout.ts: your site’s name as a label, the heading, the text, the button and the signature. Email programs ignore stylesheets, so the colors are written into the HTML from your brand (from Brand in the content editor: the light theme’s colors, or the dark board in Chalk), and the fonts are system fonts. Change the brand colors and the emails follow. To change the layout itself, edit layout.ts; keep the styles inline.

Each email also has a plain-text version for email programs that prefer it.

There is no preview page; send them to yourself instead.

  1. Set up Resend (or skip it and watch the terminal lines).
  2. Make sure site in astro.config.mjs is right if you want to test the buttons.
  3. Trigger each email with your own address:
    • Contact message: set Site settings → Email to your inbox and send the contact form.
    • Welcome emails: sign up with an address that isn’t on the list yet (a second sign-up with the same address sends nothing). With Gmail, you+test1@gmail.com counts as a new address.
    • Payment email: make a test purchase with the Stripe CLI and the card 4242 4242 4242 4242, as in Payments.
  4. In Resend, Emails lists everything sent, with its status; open one to see it as sent.
What you see Why, and what to do
Only [email] to … lines in the terminal RESEND_API_KEY isn’t set, or the server wasn’t restarted
Resend error 403 (or similar) in the log EMAIL_FROM isn’t on a verified domain. The template’s example sender can’t send
The welcome email never comes, the sign-up works The address was already on the list, or sending failed: look for [waitlist] onJoin failed in the log
The payment email never comes The webhook didn’t run: see Payments → Troubleshooting
Buttons open the demo site site in astro.config.mjs is still the demo address
A {placeholder} shows literally It isn’t one this email knows. Check the email’s file for the available ones