Change email content
To change the content of the default email templates, you can override the getContent function in the emailDelivery object. It allows you to return an object that has the following properties:
- body: This is the email's body. This can be HTML or just text as well.
- isHtml: If the body is HTML, then this should be- true.
- subject: This is the subject of the email to send.
- toEmail: The email will be sent to this email.
Other information like which email ID to send from is specified in the smtpSettings object.
- NodeJS
- GoLang
- Python
- Other Frameworks
Important
For other backend frameworks, you can follow our guide on how to spin up a separate server configured with the SuperTokens backend SDK  to authenticate requests and issue session tokens.
import supertokens from "supertokens-node";
import Passwordless from "supertokens-node/recipe/passwordless";
import Session from "supertokens-node/recipe/session";
import { SMTPService } from "supertokens-node/recipe/passwordless/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: [
        Passwordless.init({
            emailDelivery: {
                service: new SMTPService({
                    smtpSettings: { /*...*/ },
                    override: (originalImplementation) => {
                        return {
                            ...originalImplementation,
                            getContent: async function (input) {                               
                                let {
                                    isFirstFactor,
                                    codeLifetime, // amount of time the code is alive for (in MS)
                                    email,
                                    urlWithLinkCode, // magic link
                                    userInputCode, // OTP
                                } = input;
                                if (isFirstFactor) {
                                    // this is for first factor login
                                    return {
                                        body: "EMAIL BODY",
                                        isHtml: true,
                                        subject: "Login to your account",
                                        toEmail: email
                                    }
                                } else {
                                    // this is for MFA login (only applicable if you are using MFA).
                                    // In this case, the urlWithLinkCode will always be undefined since 
                                    // we only support OTP based MFA and not link based MFA
                                    return {
                                        body: "EMAIL BODY",
                                        isHtml: true,
                                        subject: "Login via MFA",
                                        toEmail: email
                                    }
                                }
                                // You can even call the original implementation and
                                // modify its content:
                                
                                /*
                                let originalContent = await originalImplementation.getContent(input)
                                originalContent.subject = "My custom subject";
                                return originalContent;
                                */
                            }
                        }
                    }
                })
            }
        }),
        // if email verification is enabled
        EmailVerification.init({
            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()
    ]
});
import (
    "fmt"
    "github.com/supertokens/supertokens-golang/ingredients/emaildelivery"
    "github.com/supertokens/supertokens-golang/recipe/emailverification"
    "github.com/supertokens/supertokens-golang/recipe/emailverification/evmodels"
    "github.com/supertokens/supertokens-golang/recipe/passwordless"
    "github.com/supertokens/supertokens-golang/recipe/passwordless/plessmodels"
    "github.com/supertokens/supertokens-golang/supertokens"
)
func main() {
    supertokens.Init(supertokens.TypeInput{
        RecipeList: []supertokens.Recipe{
            passwordless.Init(plessmodels.TypeInput{
                EmailDelivery: &emaildelivery.TypeInput{
                    Service: passwordless.MakeSMTPService(emaildelivery.SMTPServiceConfig{
                        Settings: emaildelivery.SMTPSettings{ /* ... */ },
                        Override: func(originalImplementation emaildelivery.SMTPInterface) emaildelivery.SMTPInterface {
                            (*originalImplementation.GetContent) = func(input emaildelivery.EmailType, userContext supertokens.UserContext) (emaildelivery.EmailContent, error) {
                                // amount of time the code is alive for (in MS)
                                codeLifetime := input.PasswordlessLogin.CodeLifetime
                                email := input.PasswordlessLogin.Email
                                // magic link
                                urlWithLinkCode := input.PasswordlessLogin.UrlWithLinkCode
                                // OTP
                                userInputCode := input.PasswordlessLogin.UserInputCode
                                fmt.Println(codeLifetime)
                                fmt.Println(email)
                                fmt.Println(urlWithLinkCode)
                                fmt.Println(userInputCode)
                                // send some custom email content
                                return emaildelivery.EmailContent{
                                    Body:    "EMAIL BODY",
                                    IsHtml:  true,
                                    Subject: "Some subject",
                                    ToEmail: email,
                                }, nil
                            }
                            return originalImplementation
                        },
                    }),
                },
            }),
            // if email verification is enabled
            emailverification.Init(evmodels.TypeInput{
                EmailDelivery: &emaildelivery.TypeInput{
                    Service: emailverification.MakeSMTPService(emaildelivery.SMTPServiceConfig{
                        Settings: emaildelivery.SMTPSettings{ /* ... */ },
                        Override: func(originalImplementation emaildelivery.SMTPInterface) emaildelivery.SMTPInterface {
                            originalGetContent := *originalImplementation.GetContent
                            (*originalImplementation.GetContent) = func(input emaildelivery.EmailType, userContext supertokens.UserContext) (emaildelivery.EmailContent, error) {
                                // email verification email content
                                emailVerificationLink := input.EmailVerification.EmailVerifyLink
                                user := input.EmailVerification.User
                                fmt.Println(emailVerificationLink)
                                fmt.Println(user)
                                // you can even call the original implementation and modify that
                                originalContent, err := originalGetContent(input, userContext)
                                if err != nil {
                                    return emaildelivery.EmailContent{}, err
                                }
                                originalContent.Subject = "My custom subject"
                                return originalContent, nil
                            }
                            return originalImplementation
                        },
                    }),
                },
            }),
        },
    })
}
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import passwordless
from supertokens_python.ingredients.emaildelivery.types import EmailDeliveryConfig, EmailContent, SMTPSettings
from supertokens_python.recipe.passwordless.types import SMTPOverrideInput, EmailTemplateVars
from typing import Dict, Any
from supertokens_python.recipe.emailverification.types import SMTPOverrideInput as EVSMTPOverrideInput, EmailTemplateVars as EVEmailTemplateVars
from supertokens_python.recipe import emailverification
def custom_smtp_content_override(original_implementation: SMTPOverrideInput) -> SMTPOverrideInput:
    original_get_content = original_implementation.get_content
    async def get_content(template_vars: EmailTemplateVars, user_context: Dict[str, Any]) -> EmailContent:
        _ = template_vars.url_with_link_code # magic link content
        __ = template_vars.email
        ___ = template_vars.user_input_code # OTP
        # you can even call the original implementation and modify that
        original_content = await original_get_content(template_vars, user_context)
        original_content.subject = "My custom subject"
        return original_content
    original_implementation.get_content = get_content
    return original_implementation
def custom_smtp_email_verification_content_override(original_implementation: EVSMTPOverrideInput) -> EVSMTPOverrideInput:
    original_get_content = original_implementation.get_content
    async def get_content(template_vars: EVEmailTemplateVars, user_context: Dict[str, Any]) -> EmailContent:
        # email verification content
        _ = template_vars.email_verify_link
        __ = template_vars.user
        # you can even call the original implementation and modify that
        original_content = await original_get_content(template_vars, user_context)
        original_content.subject = "My custom subject"
        return original_content
    original_implementation.get_content = get_content
    return original_implementation
init(
    app_info=InputAppInfo(
        api_domain="...", app_name="...", website_domain="..."),
    framework='...',  
    recipe_list=[
        passwordless.init(
            email_delivery=EmailDeliveryConfig(
                service=passwordless.SMTPService(
                    smtp_settings=SMTPSettings(...),  
                    override=custom_smtp_content_override
                )
            )
        ),
        # If email verification is enabled
        emailverification.init(
            mode="OPTIONAL",
            email_delivery=EmailDeliveryConfig(
                service=emailverification.SMTPService(
                    smtp_settings=SMTPSettings(...),  
                    override=custom_smtp_email_verification_content_override
                )
            )
        )
    ]
)