FYI: You can also add or remove existing emails with the email.config.ts.

Prerequisites

Before customising our emails, please make sure to replace the [INSERT_LOGO_URL] and [INSERT_COMPANY_NAME] in the emails. You can use a tool like Imgur to host the image and then use the URL in the emails.

Setting Up Resend

1

Creating a Resend account

You can sign up for a free account here

2

Setting up SMTP in Supabase

Please refer to the Resend SMTP documentation to learn more about how to set up Resend SMTP in Supabase.

3

Setting up Supabase Emails

Supabase has a set of built-in emails that are used for various purposes such as sign up, email confirmation, etc.

  1. Download all the email templates here required for the Supabase Emails, e.g., Confirm Email Change, Password Reset, etc.
  2. Paste each email into its corresponding email template which can be found in the Supabase dashboard under Email Templates

In order for the authentication to work we need to use a token_hash inside the URL. Here are the paths for each email.

This step isn’t required if the emails have been downloaded and copied as mentioned in the previous step. This is just an FYI of how it works.

For the Confirm Signup email, we need to use the following path:

{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=signup

For the Magic Link email, we need to use the following path:

{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=magiclink

For the Change Email Address email, we need to use the following path:

{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email_change

For the Reset Password email, we need to use the following path:

{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=recovery
4

Setting Up Custom Transactional Emails (Optional)

This boilerplate comes with a set of custom transactional emails that are used for various purposes including: free trial started, free trial expires soon and referral invites.

FYI: Including these custom transactional emails is optional but provides a more pleasant user experience.

Inside our email.config.ts enable or disable the desired emails. That’s it.

export const emailConfig: EmailConfigType = {
    [EmailType.FREE_TRIAL_STARTED]: {
        component: FreeTrialStartedEmail,
        isEnabled: false,
    },
    [EmailType.FREE_TRIAL_EXPIRES_SOON]: {
        component: FreeTrialExpiresEmail,
        isEnabled: false,
    },
};

This boilerplate uses React Email under the hood for the emails. Thus, all emails can be further customised if desired.

cd react-email-starter && npm run dev

How to add new Emails:

1

Updating The Email Schema

The emails inside this boilerplate were created with React Email.

To create a new email, please create one under the react-email-starter/emails folder and add a new schema inside the resend.ts file for it (so the props that the email will receive):

    export const emailSchemas = {
        [EmailType.FREE_TRIAL_STARTED]: z.object({
            trialDuration: z.number(),
            trialEndDate: z.string(),
        }),
        [EmailType.FREE_TRIAL_EXPIRES_SOON]: z.object({
            trialDuration: z.number(),
            discountCode: z.string(),
        }),
        [EmailType.REFERRAL_INVITE]: z.object({
            nameOfReferrer: z.string(),
            referralCode: z.string(),
        }),
        ...
    };
2

Updating the emailConfig

Then, we also need to import our new email inside our send-email route under the emailConfig object.

FYI: The emailConfig needs to reside inside the API route itself and can’t be outsourced into its own email.confi.ts file because this would throw an error when building the app as the environments are different.

const emailConfig: EmailConfigType = {
    [EmailType.FREE_TRIAL_STARTED]: {
        component: FreeTrialStartedEmail,
        isEnabled: false,
    },
    [EmailType.FREE_TRIAL_EXPIRES_SOON]: {
        component: FreeTrialExpiresEmail,
        isEnabled: false,
    },
    [EmailType.REFERRAL_INVITE]: {
        component: ReferralInviteEmail,
        isEnabled: true,
    },
};