Configuration

Email Service Setup

In this project, Resend is used for sending emails. Follow these steps to set it up:

  1. Log in to your existing [Resend account] or create a new one.

  2. Connect your domain in the Resend dashboard under the DOMAINS tab. You’ll be guided through the process by Resend.

  3. Inside the Resend dashboard, go to the API KEYS tab and create a new one.

  4. Include the API Key in your .env.local file:

    .env.local
    NEXT_PUBLIC_RESEND_EMAIL_API_KEY=
  5. Upload your company logo to [Imgur] or another image hosting service. This image will be used in the email templates.

  6. Update the .env.local file with your new logo URL from Imgur. It should have the following format: https://i.imgur.com/...

    .env.local
    NEXT_PUBLIC_EMAIL_LOGO_BASE_URL=
  7. In the TextConstants.ts file, update the following constants with your own values. These are used in the email templates.

TextConstants.ts
TextConstants.EMAIL__SEND_FROM:
TextConstants.EMAIL__LOOM_GETTING_STARTED_URL:
TextConstants.EMAIL__COMPANy_TITLE:
TextConstants.EMAIL__TWITTER_COMPANy_TAG:
TextConstants.EMAIL__TWITTER_COMPANy_URL:
TextConstants.TEXT__TWITTER_FOUNDER_TAG:
TextConstants.EMAIL__TWITTER_FOUNDER_URL:
TextConstants.EMAIL__FREE_TRIAL_DURATION:

Feel free to update the email templates as needed to match your branding and either remove constants or add new ones as needed.

Connecting Supabase and Resend

Supabase and Resend are used together so that Supabase can send sign up confirmations, password reset emails, etc.

  1. In the Resend dashboard, go to the DOMAINS tab and add a new domain (if not already added).
  2. Follow the [setup instructions in this tutorial], starting from 2 minutes and 28 seconds.
  3. Verify the configuration. That is, make sure all Supabase emails are now routed through Resend - whenever an email is sent within Supabase, it should also be visible in Resend.

Use a subdomain (e.g. notifications.exampledomain.com instead of exampledomain.com)! Otherwise, your root domain reputation will be negatively impacted when DDoSed.

Email Templates

Supabase has a lot of built-in email templates that can be used for different purposes such a sign-up confirmation, inviting user, resetting password and reauthenticating. You can find these templates under the authentication tab and then clicking on EMAIL TEMPLATES.

However, it doesn’t come with custom features that we added such as when a user purchases a paid plan or starts a free trial. Hence, we’ll be using Resend to create custom email templates for these.

I’ve created two templates (FreeTrialEmailTemplate.tsx and PaidPlanEmailTemplate.tsx). These can be found inside the codebase under the EMAILS folder.

      • FreeTrialEmailTemplate.tsx
      • PaidPlanEmailTemplate.tsx

Custom Email Templates

These are the CONFIRM SIGNUP and RESET PASSWORDS templates that I’ve customised for this SaaS Boilerplate. You can update them in Supabase when going to the authentication tab and then clicking on the EMAIL TEMPLATES tab.

// Confirm Signup
 
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Confirm your email for {{ .SiteURL }}</title>
        <style>
            body {
                background-color: white;
                font-family: sans-serif;
                padding: 2px;
            }
            .container {
                border: 1px solid #e5e7eb;
                border-radius: 4px;
                margin: 40px auto;
                padding: 20px;
                max-width: 465px;
            }
            .logo {
                display: block;
                margin: 32px auto 0;
                width: 48px;
                height: 48px;
            }
            h1 {
                color: black;
                font-size: 24px;
                font-weight: normal;
                text-align: center;
                padding: 0;
                margin: 30px 0;
            }
            p {
                color: black;
                font-size: 14px;
                line-height: 24px;
            }
            .button {
                background-color: black;
                border-radius: 4px;
                color: white;
                display: block;
                font-size: 14px;
                font-weight: 500;
                margin: 32px auto;
                padding: 10px 0;
                text-align: center;
                text-decoration: none;
                width: 100%;
            }
            .link {
                color: #4b5563;
                font-size: 12px;
                line-height: 20px;
                text-align: center;
                font-style: italic;
                margin-bottom: 24px;
            }
            hr {
                border: none;
                border-top: 1px solid #e5e7eb;
                margin: 26px 0;
                width: 100%;
            }
            .footer {
                color: #6b7280;
                font-size: 12px;
                line-height: 24px;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <img src="https://i.imgur.com/e0cWC6I.png" alt="Forj" class="logo" />
            <h1>Confirmation Required</h1>
            <p>Hi!</p>
            <p>Thank you for signing up with Forj! We're excited to have you on board!</p>
            <p>To get started, please confirm your email address by clicking the button below:</p>
            <a
                href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=signup"
                class="button"
                >Confirm Email</a
            >
            <p class="link">
                you can also copy and paste this link into your browser: {{ .SiteURL
                }}/auth/confirm?token_hash={{ .TokenHash }}&type=signup
            </p>
            <p>
                If you didn't create an account with us, please ignore this email or contact us at
                <strong>hello@joinforj.com</strong>, if you have any questions.
            </p>
            <hr />
            <p class="footer">
                Much love,<br />
                Timo Hünnebeck
            </p>
        </div>
    </body>
</html>
// Reset Passwords
 
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Reset your Password for {{ .SiteURL }}</title>
        <style>
            body {
                background-color: white;
                font-family: sans-serif;
                padding: 2px;
            }
            .container {
                border: 1px solid #e5e7eb;
                border-radius: 4px;
                margin: 40px auto;
                padding: 20px;
                max-width: 465px;
            }
            .logo {
                display: block;
                margin: 32px auto 0;
                width: 48px;
                height: 48px;
            }
            h1 {
                color: black;
                font-size: 24px;
                font-weight: normal;
                text-align: center;
                padding: 0;
                margin: 30px 0;
            }
            p {
                color: black;
                font-size: 14px;
                line-height: 24px;
            }
            .button {
                background-color: black;
                border-radius: 4px;
                color: white;
                display: block;
                font-size: 14px;
                font-weight: 500;
                margin: 32px auto;
                padding: 10px 0;
                text-align: center;
                text-decoration: none;
                width: 100%;
            }
            .link {
                color: #4b5563;
                font-size: 12px;
                line-height: 20px;
                text-align: center;
                font-style: italic;
                margin-bottom: 24px;
            }
            hr {
                border: none;
                border-top: 1px solid #e5e7eb;
                margin: 26px 0;
                width: 100%;
            }
            .footer {
                color: #6b7280;
                font-size: 12px;
                line-height: 24px;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <img src="https://i.imgur.com/e0cWC6I.png" alt="Forj" class="logo" />
            <h1>Password Reset Request</h1>
            <p>Hi!</p>
            <p>
                We received a request to reset your password for your Forj account. If you didn't
                make this request, please ignore this email.
            </p>
            <p>To reset your password, please click the button below:</p>
            <a href="{{ .ConfirmationURL }}" class="button">Reset Password</a>
            <p class="link">
                you can also copy and paste this link into your browser: {{ .ConfirmationURL }}
            </p>
            <p>
                This password reset link will expire in 24 hours. If you need to reset your password
                after that, please request a new reset link.
            </p>
            <p>
                If you have any questions or concerns, please contact us at
                <strong>hello@joinforj.com</strong>.
            </p>
            <hr />
            <p class="footer">
                Much love,<br />
                Timo Hünnebeck
            </p>
        </div>
    </body>
</html>