Skip to main content
This page covers both email contact sync (building your mailing list) and auth emails (magic links, password resets). One provider handles both jobs.

What Email Does in This Repo

The email service handles two things through a single provider:
  1. Contact sync — when a user signs in, they’re created as a contact in your email tool
  2. Auth emails — magic link and password reset emails are delivered through the same provider
This means you can build a mailing list, sync user data, and handle auth emails all from one place.
If contact sync fails, sign-in still works normally. Auth email delivery is stricter because the user needs that email to finish the flow.

Pick Your Provider

Best for: Simple defaults, easy contact syncing, and templated auth emails.Loops uses transactional template IDs for auth emails, so you’ll create the email templates in Loops and reference them by ID.
NEXT_PUBLIC_EMAIL_PROVIDER=loops
LOOPS_API_KEY=your-api-key
AUTH_EMAIL_FROM="YourApp <[email protected]>"
LOOPS_AUTH_MAGIC_LINK_TRANSACTIONAL_ID=your-template-id
LOOPS_AUTH_RESET_PASSWORD_TRANSACTIONAL_ID=your-template-id
Don’t forget the transactional template IDs. Without them, Loops won’t know which email to send for magic links and password resets.

Provider Selection

Set the provider with:
NEXT_PUBLIC_EMAIL_PROVIDER=loops
You can optionally add a server-only override that takes priority:
EMAIL_PROVIDER=loops
Supported values: loops, resend, brevo, none

Setup

1

Pick a provider

Choose Loops, Resend, or Brevo based on your needs.
2

Create an account and get your API key

Sign up with your chosen provider and generate an API key.
3

Add env vars to .env.local

Add the provider-specific env vars from the tabs above.
4

Set up templates (Loops only)

If you’re using Loops, create transactional email templates for magic links and password resets, then add their IDs to your env vars.
5

Restart and test

Restart the app, sign in with a test account, and request a magic link or password reset email. Confirm the contact appears in your provider’s dashboard.

Key Files

  • lib/email/contacts.ts — contact sync logic
  • lib/email/providers/* — provider-specific implementations
  • lib/email/auth-emails.ts — auth email delivery

Verify It Works

Your email setup is correct if:
  • A test user signs in successfully
  • Auth emails arrive for magic link and forgot password
  • The user appears in your chosen email provider
  • The app still works even if contact sync temporarily fails

Common Mistakes

Make sure NEXT_PUBLIC_EMAIL_PROVIDER is exactly loops, resend, or brevo. Typos will silently disable email.
Auth emails need a sender address. Without AUTH_EMAIL_FROM, delivery will fail.
Loops requires LOOPS_AUTH_MAGIC_LINK_TRANSACTIONAL_ID and LOOPS_AUTH_RESET_PASSWORD_TRANSACTIONAL_ID. Without them, auth emails won’t send.
If you reference a segment, list, or attribute that doesn’t exist in your provider, contact sync will fail silently.
EMAIL_PROVIDER=none disables everything. No contact sync, no auth emails.