Email delivery
Overview
SuperTokens sends emails in different authentication scenarios.
The method applies in the EmailPassword
, Passwordless
, and AccountLinking
recipes.
The following page shows you how to configure the email delivery method and adjust the content that gets sent to your users.
Delivery methods
Default service
If you provide no configuration for email delivery, the backend SDK sends emails by talking to the servers on https://api.supertokens.com
This applies to both self hosted and managed services.
- No info sent to the API that sends out emails on behalf of your app is logged or stored.
- The system sends emails using
noreply@supertokens.io
email ID. If you want to use your own domain, please see one of the other methods in this section. - You cannot customize the email template when using this method. If you want to customize the emails, please see one of the other methods in this section.
- Emails sent via the service are free and may land up in user's spam due to the high number of apps that use the service. If you want to avoid this, we recommend using one of the other methods mentioned in this section.
SMTP service
Using this method, you can provide your own SMTP server's configuration and the system sends the emails using those. Use this method if you want to:
- Send emails using your own domain.
- Optionally customize the default email template and subject.
import supertokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import Session from "supertokens-node/recipe/session";
import { SMTPService } from "supertokens-node/recipe/emailpassword/emaildelivery";
import EmailVerification from "supertokens-node/recipe/emailverification"
import { SMTPService as EmailVerificationSMTPService } from "supertokens-node/recipe/emailverification/emaildelivery";
let smtpSettings = {
host: "...",
authUsername: "...", // this is optional. In case not given, from.email will be used
password: "...",
port: 465,
from: {
name: "...",
email: "...",
},
secure: true
}
supertokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
EmailPassword.init({
emailDelivery: {
service: new SMTPService({smtpSettings})
},
}),
// if email verification is enabled..
EmailVerification.init({
mode: "OPTIONAL",
emailDelivery: {
service: new EmailVerificationSMTPService({smtpSettings})
}
}),
Session.init()
]
});
Custom method
This method allows you to define your own email sending abstraction.
import supertokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import Session from "supertokens-node/recipe/session";
import EmailVerification from "supertokens-node/recipe/emailverification"
supertokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
EmailPassword.init({
emailDelivery: {
override: (originalImplementation) => {
return {
...originalImplementation,
sendEmail: async function (input) {
// TODO: create and send password reset email
// Or use the original implementation which calls the default service,
// or a service that you may have specified in the emailDelivery object.
return originalImplementation.sendEmail(input);
}
}
}
},
}),
// if email verification is enabled
EmailVerification.init({
mode: "OPTIONAL",
emailDelivery: {
override: (originalImplementation) => {
return {
...originalImplementation,
sendEmail: async function (input) {
// TODO: create and send email verification email
// Or use the original implementation which calls the default service,
// or a service that you may have specified in the emailDelivery object.
return originalImplementation.sendEmail(input);
}
}
}
},
}),
Session.init()
]
});
If you call the original implementation function for sendEmail
, it uses the service that you have configured. If you have not configured any service, it uses the default service.
Using this method, you can, for example, have your custom way of sending email verification emails, but use the default or SMTP service to send the reset password emails.
Email content customization
You can access the default email UI through the following links:
- Default email verification template and its source code.
- Default password reset template and its source code.
To change the content you can create a custom SMTPService
like and update the property which builds the content.
The method allows you to return an object that has the following properties:
body
: This is the email's body. This can be HTML or text as well.isHtml
: If the body is HTML, then this should betrue
.subject
: This is the subject of the email to send.toEmail
: The system sends the email to this email.
Other information like which email ID to send from appears in the smtpSettings
object.
import supertokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import Session from "supertokens-node/recipe/session";
import { SMTPService } from "supertokens-node/recipe/emailpassword/emaildelivery";
import EmailVerification from "supertokens-node/recipe/emailverification"
import { SMTPService as EmailVerificationSMTPService } from "supertokens-node/recipe/emailverification/emaildelivery";
supertokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
EmailPassword.init({
emailDelivery: {
service: new SMTPService({
smtpSettings: { /*...*/ },
override: (originalImplementation) => {
return {
...originalImplementation,
getContent: async function (input) {
// password reset content
let { passwordResetLink, user } = input;
// you can even call the original implementation and modify that
let originalContent = await originalImplementation.getContent(input)
originalContent.subject = "My custom subject";
return originalContent;
}
}
}
})
}
}),
// if email verification is enabled
EmailVerification.init({
mode: "OPTIONAL",
emailDelivery: {
service: new EmailVerificationSMTPService({
smtpSettings: { /*...*/ },
override: (originalImplementation) => {
return {
...originalImplementation,
getContent: async function (input) {
// email verification content
let { emailVerifyLink, user } = input;
// you can even call the original implementation and modify that
let originalContent = await originalImplementation.getContent(input)
originalContent.subject = "My custom subject";
return originalContent;
}
}
}
})
}
}),
Session.init()
]
});
Overrides
You can use the override functionality to trigger any kind of behavior before and after email sending. This can include things like:
- Logging
- Spam protection actions
- Modifying the email template variables before sending the emails
import supertokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import Session from "supertokens-node/recipe/session";
import EmailVerification from "supertokens-node/recipe/emailverification"
supertokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
EmailPassword.init({
emailDelivery: {
override: (originalImplementation) => {
return {
...originalImplementation,
sendEmail: async function (input) {
// TODO: run some logic before sending the email
await originalImplementation.sendEmail(input);
// TODO: run some logic post sending the email
}
}
}
},
}),
// if email verification is enabled
EmailVerification.init({
mode: "OPTIONAL",
emailDelivery: {
override: (originalImplementation) => {
return {
...originalImplementation,
sendEmail: async function (input) {
// TODO: run some logic before sending the email
await originalImplementation.sendEmail(input);
// TODO: run some logic post sending the email
}
}
}
},
}),
Session.init()
]
});