> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getsabo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Auth Emails with Resend

> Customize Supabase Auth email templates, connect Resend SMTP, and improve deliverability.

<Info>
  This guide covers customizing Supabase Auth emails (sign up verification, magic link, password reset), connecting Resend for SMTP delivery, and applying deliverability best practices.
</Info>

## Overview

Supabase Auth sends three types of emails:

| Email Type             | Trigger                           | Purpose                                   | Default Template    |
| ---------------------- | --------------------------------- | ----------------------------------------- | ------------------- |
| **Confirmation Email** | User signs up with email/password | Verify email address before first sign-in | Signup confirmation |
| **Magic Link**         | User chooses passwordless sign-in | One-click authentication without password | Magic link          |
| **Password Reset**     | User clicks "Forgot password"     | Secure password reset via email link      | Reset password      |

All emails are sent via Supabase's email service by default, but you can connect **Resend** (or any SMTP provider) for better deliverability, custom domains, and branded emails.

## Prerequisites

* Supabase project with Authentication enabled
* (Recommended) Resend account with verified domain (SPF/DKIM/DMARC)

<Steps>
  <Step title="Configure URLs (Supabase)">
    Go to Supabase → Authentication → Configuration → <b>URL Configuration</b> and set:

    * <b>Site URL</b> (per environment)
    * <b>Additional Redirect URLs</b>: include <code>/auth/callback</code> for dev/preview/prod domains

    <Check>
      Auth links in emails redirect to your app and complete the callback flow.
    </Check>
  </Step>

  <Step title="Connect Resend (SMTP)">
    Two options:

    * Option A: Use Supabase Integrations to connect Resend (auto SMTP configuration)
    * Option B: Get SMTP credentials from Resend and set them under Supabase → Authentication → Emails → <b>SMTP Settings</b>

    <Warning>
      Verify your domain in Resend (SPF, DKIM) before going live for proper deliverability.
    </Warning>

    <Check>
      Test emails from Supabase are delivered through Resend with your domain as sender.
    </Check>
  </Step>

  <Step title="Edit email templates (Supabase)">
    Go to Supabase → Authentication → Emails → <b>Templates</b> to edit subject, sender, and body for each email type.

    ### Available Templates

    | Template                 | When Sent                          | Customizable Fields        | Template Variables                                         |
    | ------------------------ | ---------------------------------- | -------------------------- | ---------------------------------------------------------- |
    | **Confirm signup**       | After email/password sign-up       | Subject, Sender, HTML Body | `{{ .ConfirmationURL }}`, `{{ .SiteURL }}`, `{{ .Token }}` |
    | **Magic link**           | User requests passwordless sign-in | Subject, Sender, HTML Body | `{{ .ConfirmationURL }}`, `{{ .SiteURL }}`, `{{ .Token }}` |
    | **Change email address** | User updates email in settings     | Subject, Sender, HTML Body | `{{ .ConfirmationURL }}`, `{{ .SiteURL }}`, `{{ .Token }}` |
    | **Reset password**       | User clicks "Forgot password"      | Subject, Sender, HTML Body | `{{ .ConfirmationURL }}`, `{{ .SiteURL }}`, `{{ .Token }}` |

    ### Template Variables

    Each email template has access to these variables:

    ```html theme={null}
    <!-- Main confirmation URL (includes token) -->
    {{ .ConfirmationURL }}

    <!-- Your site URL (from Supabase settings) -->
    {{ .SiteURL }}

    <!-- Raw token (for custom redirect URLs) -->
    {{ .Token }}

    <!-- Token hash (for OTP verification) -->
    {{ .TokenHash }}

    <!-- Email address (recipient) -->
    {{ .Email }}
    ```

    ### Example: Custom Magic Link Template

    ```html theme={null}
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Sign in to YourApp</title>
    </head>
    <body>
      <h1>Your magic link is ready</h1>
      <p>Click the button below to sign in to your account:</p>
      
      <a href="{{ .ConfirmationURL }}" style="...">
        Sign in to YourApp
      </a>
      
      <p>Or copy this link:</p>
      <code>{{ .ConfirmationURL }}</code>
      
      <p>This link expires in 1 hour.</p>
      
      <hr>
      <p>Didn't request this? You can safely ignore this email.</p>
    </body>
    </html>
    ```

    <Tip>
      **Best practices for email templates:**

      * Use clear, actionable subject lines (e.g., "Confirm your email" not "Action required")
      * Include your logo and brand colors
      * Keep CTA buttons visible above the fold
      * Provide fallback text link in case button doesn't render
      * Add expiration time (e.g., "This link expires in 1 hour")
      * Include security disclaimer (e.g., "Didn't request this? Ignore this email")
    </Tip>

    <Warning>
      **Tracking links can break authentication:**

      For Auth emails, **disable link/open tracking** in Resend or your SMTP provider. Tracking services rewrite URLs, which can break Supabase's one-time magic links.

      **How to disable tracking:**

      * **Resend**: Go to Settings → Tracking → Disable for auth emails
      * **SendGrid**: Add `tracking_settings.click_tracking.enable: false`
      * **Mailgun**: Set `o:tracking-clicks` to `no`
    </Warning>

    <Note>
      **Security scanner prefetch protection:**

      Some corporate email security scanners automatically "click" links in emails to check for malware. This can consume one-time magic links before users click them.

      **Solution:** Implement an intermediate landing page:

      1. Instead of direct magic link: `https://yourapp.com/auth/callback?token_hash=...`
      2. Use intermediate page: `https://yourapp.com/auth/verify?token=...`
      3. Show "Click to continue" button on intermediate page
      4. Button then redirects to actual `/auth/callback` with token

      This prevents scanners from consuming the real magic link.
    </Note>

    <Check>
      Test each template by:

      1. Triggering the email flow (sign up, magic link, password reset)
      2. Checking inbox for email (also check spam)
      3. Verifying links work correctly
      4. Testing on multiple email clients (Gmail, Outlook, Apple Mail)
    </Check>
  </Step>

  <Step title="Deliverability best practices">
    * Match the <b>sender domain</b> and <b>link domain</b> (use a custom domain)
    * Use a <b>dedicated subdomain</b> for auth emails (e.g., <code>auth.yourdomain.com</code>)
    * <b>Disable tracking</b> on Auth emails
    * Configure <b>DMARC</b> alongside SPF/DKIM
    * Mitigate <b>link scanners</b> with an intermediate page pattern

    <Check>
      Emails land in inbox (not spam) for Gmail/Outlook; links function reliably.
    </Check>
  </Step>

  <Step title="End‑to‑end testing">
    Test all three email flows to ensure everything works:

    ### 1. Confirmation Email Test

    <Tabs>
      <Tab title="Sign Up Flow">
        1. Go to `/sign-up`
        2. Enter name and email
        3. Choose "Create password" option
        4. Submit form
        5. **Expected:** Confirmation email arrives
        6. Click link in email
        7. **Expected:** Redirected to `/dashboard`
        8. Verify you can sign in
      </Tab>

      <Tab title="Email Not Received?">
        **Check these common issues:**

        1. **Spam folder** - Auth emails often land in spam initially
        2. **Email address typo** - Double-check the email you entered
        3. **Supabase email rate limit** - Default: 4 emails/hour during development
        4. **SMTP configuration** - Verify Resend credentials if using custom SMTP
        5. **Email confirmation disabled** - Check Supabase → Auth → Settings → Email Auth

        **To debug:**

        * Check Supabase Dashboard → Logs → Auth Logs for errors
        * Check Resend Dashboard → Logs for delivery status
        * Test with a different email provider (Gmail vs custom domain)
      </Tab>
    </Tabs>

    ### 2. Magic Link Test

    <Tabs>
      <Tab title="Magic Link Flow">
        1. Go to `/sign-in`
        2. Enter email
        3. Click "Send magic link" button
        4. **Expected:** Magic link email arrives
        5. Click link in email
        6. **Expected:** Redirected to `/dashboard`
        7. Verify you're signed in
      </Tab>

      <Tab title="Link Not Working?">
        **Common issues:**

        1. **Link expired** - Magic links expire after 1 hour
        2. **Link already used** - Magic links are one-time use
        3. **Link tracking enabled** - Disable click tracking in email provider
        4. **Security scanner prefetch** - Implement intermediate landing page
        5. **Browser cookie issues** - Try in incognito/private mode

        **Error message: "auth\_failed"**

        * Link expired or already used
        * Request a new magic link
      </Tab>
    </Tabs>

    ### 3. Password Reset Test

    <Tabs>
      <Tab title="Reset Flow">
        1. Go to `/forgot-password`
        2. Enter email
        3. Submit form
        4. **Expected:** Redirected to `/sign-in?reset=true`
        5. **Expected:** Reset email arrives
        6. Click link in email
        7. **Expected:** Redirected to `/reset-password`
        8. Enter new password
        9. Submit form
        10. **Expected:** Redirected to `/sign-in`
        11. Sign in with new password
      </Tab>

      <Tab title="Reset Issues?">
        **Common issues:**

        1. **Email not received** - Same debugging as confirmation email
        2. **Link expired** - Reset links expire after 1 hour
        3. **Password not updated** - Check for Supabase Auth Logs errors
        4. **Still using old password** - Clear browser cache and try again

        **To verify reset worked:**

        ```bash theme={null}
        # Check Supabase Auth Logs
        Supabase Dashboard → Logs → Auth Logs → Look for "password_recovery" event
        ```
      </Tab>
    </Tabs>

    ### Testing Checklist

    * [ ] Confirmation email arrives within 1 minute
    * [ ] Email renders correctly in Gmail
    * [ ] Email renders correctly in Outlook
    * [ ] Email renders correctly in Apple Mail
    * [ ] Links work when clicked
    * [ ] Links work on mobile devices
    * [ ] Expired links show appropriate error
    * [ ] Used links show appropriate error
    * [ ] Emails don't land in spam (after Resend setup)
    * [ ] Dark mode email templates look good (if using)
  </Step>
</Steps>

## Email Flow Diagrams

### Sign-Up Confirmation Flow

```
User: /sign-up → Enter email/password → Submit
  ↓
Server: signUp() action → Supabase creates account
  ↓
Supabase: Sends confirmation email → {{ .ConfirmationURL }}
  ↓
User: Clicks link in email
  ↓
Browser: Opens /auth/callback?token_hash=...&type=signup
  ↓
Server: Verifies token → Creates session
  ↓
Browser: Redirects to /dashboard
  ↓
Result: User is signed in
```

### Magic Link Flow

```
User: /sign-in → Enter email → Click "Send magic link"
  ↓
Server: signInWithMagicLink() action → Supabase sends OTP
  ↓
Supabase: Sends magic link email → {{ .ConfirmationURL }}
  ↓
User: Clicks link in email
  ↓
Browser: Opens /auth/callback?token_hash=...&type=email
  ↓
Server: Verifies OTP → Creates session
  ↓
Browser: Redirects to /dashboard
  ↓
Result: User is signed in
```

### Password Reset Flow

```
User: /forgot-password → Enter email → Submit
  ↓
Server: sendResetEmail() action → Supabase sends recovery email
  ↓
Supabase: Sends reset email → {{ .ConfirmationURL }}
  ↓
User: Clicks link in email
  ↓
Browser: Opens /auth/callback?token_hash=...&type=recovery
  ↓
Server: Verifies token → Creates temporary session
  ↓
Browser: Redirects to /reset-password
  ↓
User: Enters new password → Submit
  ↓
Server: resetPassword() action → Updates password
  ↓
Browser: Redirects to /sign-in
  ↓
Result: Password updated
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Emails not arriving">
    **Cause:** Rate limiting, spam filters, or SMTP misconfiguration.

    **Fix:**

    1. **Check rate limits:**
       * Supabase free tier: 4 emails/hour during development
       * Production: Unlimited with verified domain
       * Upgrade plan or wait for rate limit reset

    2. **Check spam folder:**
       * Auth emails often land in spam initially
       * Use custom domain (not @resend.dev) to improve deliverability

    3. **Verify SMTP configuration:**
       * Supabase Dashboard → Auth → Emails → SMTP Settings
       * Test connection with "Send test email" button
       * Check Resend dashboard for delivery errors

    4. **Check Supabase logs:**
       * Dashboard → Logs → Auth Logs
       * Look for email send errors
       * Common error: "Email rate limit exceeded"
  </Accordion>

  <Accordion title="Links not working or showing 'auth_failed'">
    **Cause:** Expired links, already-used links, or tracking interference.

    **Fix:**

    1. **Check link expiration:**
       * Magic links: 1 hour (default)
       * Reset links: 1 hour (default)
       * Request new link if expired

    2. **Verify link hasn't been used:**
       * Auth links are one-time use
       * Already-clicked links show "auth\_failed"
       * Request new link

    3. **Disable email tracking:**
       * Resend → Settings → Tracking → Disable
       * Link tracking rewrites URLs and breaks auth

    4. **Check for security scanner prefetch:**
       * Corporate emails may "click" links automatically
       * Implement intermediate landing page pattern
  </Accordion>

  <Accordion title="Emails landing in spam">
    **Cause:** Poor sender reputation, no SPF/DKIM, or suspicious content.

    **Fix:**

    1. **Verify your domain in Resend:**
       ```bash theme={null}
       # Add these DNS records
       SPF: v=spf1 include:_spf.resend.com ~all
       DKIM: [Resend provides unique DKIM record]
       DMARC: v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com
       ```

    2. **Use custom domain:**
       * Change from: `noreply@resend.dev`
       * To: `noreply@yourdomain.com` or `auth@yourdomain.com`

    3. **Improve email content:**
       * Remove spammy words ("urgent", "verify now", excessive caps)
       * Use clear, professional language
       * Include your company logo and branding

    4. **Warm up your domain:**
       * Start with low email volume
       * Gradually increase over days/weeks
       * Monitor spam rates in Resend dashboard
  </Accordion>

  <Accordion title="Custom domain not working">
    **Cause:** DNS records not propagated or incorrectly configured.

    **Fix:**

    1. **Verify DNS records:**
       ```bash theme={null}
       # Check SPF
       dig TXT yourdomain.com | grep "v=spf1"

       # Check DKIM
       dig TXT resend._domainkey.yourdomain.com

       # Check DMARC
       dig TXT _dmarc.yourdomain.com
       ```

    2. **Wait for propagation:**
       * DNS changes can take 24-48 hours
       * Use [whatsmydns.net](https://www.whatsmydns.net) to check global propagation

    3. **Verify in Resend dashboard:**
       * Resend → Domains → Your domain should show "Verified"
       * If not, re-check DNS records match Resend's requirements

    4. **Test email sending:**
       * Resend → Domains → "Send test email"
       * Check delivery to Gmail, Outlook, Yahoo
  </Accordion>

  <Accordion title="Email templates not rendering correctly">
    **Cause:** HTML/CSS compatibility issues across email clients.

    **Fix:**

    1. **Use email-safe HTML:**
       * Tables for layout (not CSS Grid/Flexbox)
       * Inline CSS (not external stylesheets)
       * Absolute URLs for images (not relative paths)

    2. **Test across clients:**
       * [Litmus](https://www.litmus.com/) for email testing
       * [Email on Acid](https://www.emailonacid.com/) for preview
       * Test manually in Gmail, Outlook, Apple Mail

    3. **Use Resend's template testing:**
       * Resend → Templates → Preview
       * Send test emails to yourself
       * Check rendering on mobile devices

    4. **Simplify complex layouts:**
       * Email clients have limited HTML/CSS support
       * Keep layouts simple and table-based
       * Use web-safe fonts (Arial, Helvetica, Georgia)
  </Accordion>
</AccordionGroup>

## Production Checklist

Before going live, ensure:

* Custom domain verified in Resend (SPF/DKIM/DMARC configured)
* Email templates customized with your branding
* All template variables working correctly
* Link tracking disabled for auth emails
* Sender address uses your custom domain (`auth@yourdomain.com`)
* Tested all three flows (confirmation, magic link, reset) end-to-end
* Emails arrive within 1 minute
* Emails don’t land in spam for Gmail/Outlook/Yahoo
* Mobile email rendering tested
* Dark mode email templates tested (if applicable)
* Rate limits increased for production (Supabase plan upgrade)
* Monitoring set up in Resend dashboard (delivery, bounces, complaints)

## Related Documentation

<CardGroup cols={2}>
  <Card title="Auth with Supabase" icon="key" href="/core-features/auth-with-supabase">
    Complete authentication setup including sign-in, sign-up, OAuth, and password reset flows.
  </Card>

  <Card title="Environment Variables" icon="code" href="/core-features/environment-variables">
    Configure Supabase and Resend environment variables for local and production.
  </Card>

  <Card title="API Reference: Auth Callback" icon="webhook" href="/api-reference/endpoint/auth-callback">
    Detailed documentation for the `/auth/callback` endpoint that handles email verification.
  </Card>

  <Card title="Resend Docs" icon="external-link" href="https://resend.com/docs">
    Official Resend documentation for advanced email configuration and troubleshooting.
  </Card>
</CardGroup>

## References

* Supabase Dashboard (Auth → Emails → Templates): <a href="https://supabase.com/dashboard/project/_/auth/templates">Open Dashboard</a>
* Supabase × Resend Integration: <a href="https://supabase.com/partners/integrations/resend">Integration</a>
* Deliverability guide: <a href="https://resend.com/docs/knowledge-base/how-do-i-maximize-deliverability-for-supabase-auth-emails">Resend Knowledge Base</a>
* DNS Record Checker: <a href="https://www.whatsmydns.net">WhatsmyDNS</a>
* Email Testing Tools: <a href="https://www.litmus.com">Litmus</a>, <a href="https://www.emailonacid.com">Email on Acid</a>
