Customize the Magic Link
See how to change the magic link or how to generate it manually
Change the magic link URL
Override the email delivery backend function
You can change the URL of Magic Links by providing overriding the email delivery configuration on the backend.
import SuperTokens from "supertokens-node";
import Passwordless from "supertokens-node/recipe/passwordless";
import Session from "supertokens-node/recipe/session";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "...",
},
recipeList: [
Passwordless.init({
contactMethod: "EMAIL", // This example will work with any contactMethod
// This example works with the "USER_INPUT_CODE_AND_MAGIC_LINK" and "MAGIC_LINK" flows.
flowType: "USER_INPUT_CODE_AND_MAGIC_LINK",
emailDelivery: {
override: (originalImplementation) => {
return {
...originalImplementation,
sendEmail: async function (input) {
return originalImplementation.sendEmail({
...input,
urlWithLinkCode: input.urlWithLinkCode?.replace(
// This is: `<YOUR_WEBSITE_DOMAIN>/auth/verify`
"http://localhost:3000/auth/verify",
"http://your.domain.com/your/path",
),
});
},
};
},
},
}),
Session.init({
/* ... */
}),
],
});import (
"strings"
"github.com/supertokens/supertokens-golang/ingredients/emaildelivery"
"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{
Override: func(originalImplementation emaildelivery.EmailDeliveryInterface) emaildelivery.EmailDeliveryInterface {
ogSendEmail := *originalImplementation.SendEmail
(*originalImplementation.SendEmail) = func(input emaildelivery.EmailType, userContext supertokens.UserContext) error {
// By default: `<YOUR_WEBSITE_DOMAIN>//auth/verify`
newUrl := strings.Replace(
*input.PasswordlessLogin.UrlWithLinkCode,
"http://localhost:3000/auth/verify",
"http://localhost:3000/custom/path",
1,
)
input.PasswordlessLogin.UrlWithLinkCode = &newUrl
return ogSendEmail(input, userContext)
}
return originalImplementation
},
},
}),
},
})
}from supertokens_python import init, InputAppInfo
from supertokens_python.recipe.passwordless.types import EmailDeliveryOverrideInput, EmailTemplateVars
from supertokens_python.recipe import passwordless
from typing import Dict, Any
from supertokens_python.ingredients.emaildelivery.types import EmailDeliveryConfig
def custom_email_deliver(original_implementation: EmailDeliveryOverrideInput) -> EmailDeliveryOverrideInput:
original_send_email = original_implementation.send_email
async def send_email(template_vars: EmailTemplateVars, user_context: Dict[str, Any]) -> None:
assert template_vars.url_with_link_code is not None
# By default: `<YOUR_WEBSITE_DOMAIN>//auth/verify`
template_vars.url_with_link_code = template_vars.url_with_link_code.replace(
"http://localhost:3000/auth/verify", "http://localhost:3000/custom/path")
return await original_send_email(template_vars, user_context)
original_implementation.send_email = send_email
return original_implementation
init(
app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
framework='...',
recipe_list=[
passwordless.init(
email_delivery=EmailDeliveryConfig(override=custom_email_deliver)
)
]
)Change the frontend page
When the user clicks the magic link, you need to render the LinkClicked component that exported by the SDK on that page. By default, this already happens on the <YOUR_WEBSITE_DOMAIN>/auth/verify path. To change this, you need to:
1. Disable the default UI for the link clicked screen:
When the user clicks the magic link, you need to build your own UI on that page to handle the link clicked. You also need to disable the pre-built UI provided by the SDK for the link clicked screen as shown below:
import Passwordless from "supertokens-auth-react/recipe/passwordless";
Passwordless.init({
contactMethod: "EMAIL", // This example will work with any contactMethod
linkClickedScreenFeature: {
disableDefaultUI: true,
},
});// this goes in the auth route config of your frontend app (once the pre-built UI script has been loaded)
supertokensUIPasswordless.init({
contactMethod: "EMAIL", // This example will work with any contactMethod
linkClickedScreenFeature: {
disableDefaultUI: true,
},
});import React from "react";
import { LinkClicked } from "supertokens-auth-react/recipe/passwordless/prebuiltui";
function CustomLinkClickedScreen() {
return <LinkClicked />;
}Generate the link manually
You can use the backend SDK to generate magic links as shown below:
import Passwordless from "supertokens-node/recipe/passwordless";
async function createMagicLink(email: string) {
const magicLink = await Passwordless.createMagicLink({ email, tenantId: "public" });
console.log(magicLink);
}import (
"fmt"
"github.com/supertokens/supertokens-golang/recipe/passwordless"
)
func main() {
email := "..."
tenantId := "public"
magicLink, err := passwordless.CreateMagicLinkByEmail(tenantId, email)
if err != nil {
// handle error
}
fmt.Println(magicLink)
}from supertokens_python.recipe.passwordless.asyncio import create_magic_link
async def create_link(email: str):
magic_link = await create_magic_link("public", email, phone_number=None)
print(magic_link)from supertokens_python.recipe.passwordless.syncio import create_magic_link
def create_link(email: str):
magic_link = create_magic_link("public", email, phone_number=None)
print(magic_link)Change the link lifetime
You can change how long a user can use an OTP or a Magic Link to log in by changing the passwordless_code_lifetime core configuration value. You configure this value in milliseconds and it defaults to 900000 (15 minutes).
- Open the SaaS Dashboard, select the relevant Managed deployment, and open Configuration.
- In the Passwordless configuration card, change the value. Configuration changes are saved automatically.
docker run \
-p 3567:3567 \
-e PASSWORDLESS_CODE_LIFETIME=60000 \
-d supertokens/supertokens-<db name># You need to add the following to the config.yaml file.
# The file path can be found by running the "supertokens --help" command
passwordless_code_lifetime: 60000passwordless_code_lifetime: 60000