Configuration
Email Service Setup
In this project, Resend is used for sending emails. Follow these steps to set it up:
-
Log in to your existing [Resend account] or create a new one.
-
Connect your domain in the Resend dashboard under the
DOMAINS
tab. You’ll be guided through the process by Resend. -
Inside the Resend dashboard, go to the
API KEYS
tab and create a new one. -
Include the API Key in your
.env.local
file:.env.localNEXT_PUBLIC_RESEND_EMAIL_API_KEY=
-
Upload your company logo to [Imgur] or another image hosting service. This image will be used in the email templates.
-
Update the
.env.local
file with your new logo URL from Imgur. It should have the following format:https://i.imgur.com/...
.env.localNEXT_PUBLIC_EMAIL_LOGO_BASE_URL=
-
In the
TextConstants.ts
file, update the following constants with your own values. These are used in the email templates.
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.
- In the Resend dashboard, go to the
DOMAINS
tab and add a new domain (if not already added). - Follow the [setup instructions in this tutorial], starting from 2 minutes and 28 seconds.
- 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>