Skip to main content
This guide covers customizing Supabase Auth emails (sign up verification, magic link, password reset), connecting Resend for SMTP delivery, and applying deliverability best practices.

Overview

Supabase Auth sends three types of emails:
Email TypeTriggerPurposeDefault Template
Confirmation EmailUser signs up with email/passwordVerify email address before first sign-inSignup confirmation
Magic LinkUser chooses passwordless sign-inOne-click authentication without passwordMagic link
Password ResetUser clicks “Forgot password”Secure password reset via email linkReset 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)
1

Configure URLs (Supabase)

Go to Supabase → Authentication → Configuration → URL Configuration and set:
  • Site URL (per environment)
  • Additional Redirect URLs: include /auth/callback for dev/preview/prod domains
Auth links in emails redirect to your app and complete the callback flow.
2

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 → SMTP Settings
Verify your domain in Resend (SPF, DKIM) before going live for proper deliverability.
Test emails from Supabase are delivered through Resend with your domain as sender.
3

Edit email templates (Supabase)

Go to Supabase → Authentication → Emails → Templates to edit subject, sender, and body for each email type.

Available Templates

TemplateWhen SentCustomizable FieldsTemplate Variables
Confirm signupAfter email/password sign-upSubject, Sender, HTML Body{{ .ConfirmationURL }}, {{ .SiteURL }}, {{ .Token }}
Magic linkUser requests passwordless sign-inSubject, Sender, HTML Body{{ .ConfirmationURL }}, {{ .SiteURL }}, {{ .Token }}
Change email addressUser updates email in settingsSubject, Sender, HTML Body{{ .ConfirmationURL }}, {{ .SiteURL }}, {{ .Token }}
Reset passwordUser clicks “Forgot password”Subject, Sender, HTML Body{{ .ConfirmationURL }}, {{ .SiteURL }}, {{ .Token }}

Template Variables

Each email template has access to these variables:
<!-- 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 }}
<!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>
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”)
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
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.
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)
4

Deliverability best practices

  • Match the sender domain and link domain (use a custom domain)
  • Use a dedicated subdomain for auth emails (e.g., auth.yourdomain.com)
  • Disable tracking on Auth emails
  • Configure DMARC alongside SPF/DKIM
  • Mitigate link scanners with an intermediate page pattern
Emails land in inbox (not spam) for Gmail/Outlook; links function reliably.
5

End‑to‑end testing

Test all three email flows to ensure everything works:

1. Confirmation Email Test

  • Sign Up Flow
  • Email Not Received?
  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

3. Password Reset Test

  • Reset Flow
  • Reset Issues?
  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

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)

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
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

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”
Cause: Poor sender reputation, no SPF/DKIM, or suspicious content.Fix:
  1. Verify your domain in Resend:
    # 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
Cause: DNS records not propagated or incorrectly configured.Fix:
  1. Verify DNS records:
    # 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 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
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 for email testing
    • Email on Acid 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)

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)

References