Resend Setup

Workspace invites and transactional mail go through Resend; this is the minimum domain + API key setup.

1. Create a Resend account

Sign up at resend.com and get your API key from the dashboard.

2. Configure a sending domain (production)

In Resend → Domains, add your domain and configure the DNS records as instructed. This ensures emails are delivered from your custom domain (e.g., noreply@yourapp.com).

For local development, Resend lets you send to your own email without domain verification.

3. Environment variables

RESEND_API_KEY=re_...
EMAIL_FROM=YourApp <noreply@yourapp.com>

4. How invitations work

  1. OWNER/ADMIN opens the Members page and clicks Invite Member
  2. They enter an email and select a role (ADMIN, MEMBER, or VIEWER)
  3. sendInvitation() server action:
    • Validates the email and role
    • Checks for duplicate active invitations
    • Generates a secure 32-byte random token
    • Inserts an invitations row with expires_at = now() + 7 days
    • Sends an HTML email via Resend with the accept link
    • Inserts an audit log entry
  4. The invitee receives an email with a link to /invite/[token]
  5. If they're already signed in, they're added to the workspace immediately
  6. If not, they sign up / sign in and are redirected to /invite/[token] to complete acceptance

5. Customizing the email template

The HTML email template is in src/lib/email/templates/invite-email.tsx.

The template is plain HTML (no React Email dependency) for maximum compatibility. Customize the colors, copy, and logo to match your brand.

6. Disable emails in development

If RESEND_API_KEY is not set, the server action logs a warning and skips sending. The invitation is still created in the database, so you can accept it manually by visiting /invite/[token].