Magic Links
Learn how to authenticate or verify users with magic links.
Overview
Clerk supports passwordless authentication with magic links, which lets users sign in and sign up without having to remember a password. During login or registration, users will be asked to enter their email address to receive an email message with a link that can be clicked and complete the authentication process.
This one-click, link-based verification method is often referred to as a "magic link". The process is similar to sending a one-time code to your users but skipping the part where they have to come back to your app and enter the code. This is where the "magic" kicks in.
As a form of passwordless authentication, magic links arguably provide greater security and a better user experience than traditional passwords. Since there are fewer steps involved in every authentication attempt, the user experience is better than one-time codes. However, magic links are not without their downsides, and often still boil down to the email provider's "knowledge-based factor" instead of yours.
Magic links are the default passwordless authentication strategy when using Clerk. They can be used to sign up new users, sign in existing ones or allow existing users to verify newly entered email addresses to their profile.
Your users will still be able to choose an alternative authentication (or verification) method even after they've clicked the magic link they received in their inbox. Magic links are simply the default authentication method for email address-based, passwordless authentication in Clerk.
Looking for one-time code (OTP) authentication? Check out our one-time code authentication guide.
Magic link flow
Magic links can be used to easily authenticate users or verify their email addresses. In all the above cases, Clerk will take care of the plumbing and allow you to offer a seamless experience to your users:
- The user enters their email address and asks for a magic link.
- Your application waits for the verification result.
- Clerk sends an email to the user, containing a link to the verification URL.
- The user clicks the magic link. This can happen on the same device where they entered their email address, or on a different device.
- Clerk will verify the user's identity and advance any sign-in or sign-up attempt that might be in progress. In case the verification fails, Clerk will inform the user.
- Your user will now be logged in on the device or tab that they opened the link.
Magic links work on any device. There's no constraint on where the link will be opened. For example, a user might try to sign in from their desktop browser, but open the link from their mobile phone.
As an additional security measure, we expire magic links after a while. This way we can guard against cases where a stale link might be compromised. From a user experience perspective, the magic link flow is supposed to be nearly synchronous. Don't worry, your users will have plenty of time to complete the flow before the magic link expires.
Clerk provides a highly flexible API that allows you to hook into any of the above steps while abstracting away all the complexities of a magic link-based authentication or verification flow.
We take care of the boring stuff, like efficient polling, secure session management, and different device authentication so you can focus on your application code.
Before you start
- You need to create a Clerk Application in your Clerk Dashboard. For more information, check out our Set up your application guide.
- You need to install Clerk React or ClerkJS to your application.
Configuration
Magic link authentication can be configured through the Clerk Dashboard. Go to your instance, then User & Authentication > Email, Phone, Username. Simply choose Email verification link as the authentication factor.

Don't forget that you also need to make sure you've configured your application instance to request the user's email address. Users can receive magic links only via email messages. Make sure you toggle on Email address under the Contact information section. You can verify that email addresses will be used for identification, by clicking on the cog next to the Email address option and switching on the Used for identification toggle in the modal.

Don't forget to click on the Apply Changes button at the bottom of the page once you're done configuring your instance.
That's all you need to do to enable authentication with magic links for your instance.
Custom flow
In case one of the above integration methods doesn't cover your needs, you can make use of lower-level commands and create a completely custom magic link authentication flow.
You still need to configure your instance in order to enable magic link authentication, as described at the top of this guide.
Sign up using a custom flow
Registration with magic links follows a set of steps that require users to enter their email address as an authentication identifier and click on a link that's delivered to them via email message.
The sign-up process can be completed on the same or a different device. For example, users might enter their email address in their desktop browser, but click the sign-up magic link from their mobile phone. The user's email address will still be verified and registration will proceed.
Let's see all the steps involved in more detail.
- Initiate the sign-up process, by collecting the user's identifier. It must be their email address.
- Start the magic link verification flow. There are two parts to the flow:
- Prepare a verification for the email address by sending an email with a magic link to the user.
- Wait until the magic link is clicked. This is a polling behavior that can be canceled at any time.
- Handle the magic link verification result accordingly. Note that the magic link can be clicked on a different device/browser than the one which initiated the flow.
- The verification was successful so you need to continue with the sign-up flow.
- The verification failed or the magic link has expired.
Clerk provides a highly flexible API that allows you to hook into any of the above steps while abstracting away all the complexities of a magic link-based sign-up flow.
1import React from "react";2import { useRouter } from "next/router";3import {4MagicLinkErrorCode,5isMagicLinkError,6useClerk,7useSignUp8} from "@clerk/nextjs";910// pages/sign-up.jsx11// Render the sign up form.12// Collect user's email address and send a magic link with which13// they can sign up.14function SignUp() {15const [emailAddress, setEmailAddress] = React.useState("");16const [expired, setExpired] = React.useState(false);17const [verified, setVerified] = React.useState(false);18const router = useRouter();19const { signUp, setSession } = useSignUp();2021const { startMagicLinkFlow, cancelMagicLinkFlow } =22signUp.createMagicLinkFlow();2324async function submit(e) {25e.preventDefault();26setExpired(false);27setVerified(false);2829// Start the sign up flow, by collecting30// the user's email address.31await signUp.create({ emailAddress });3233// Start the magic link flow.34// Pass your app URL that users will be navigated35// when they click the magic link from their36// email inbox.37// su will hold the updated sign up object.38const su = await startMagicLinkFlow({39redirectUrl: "https://your-app.domain.com/verification",40});4142// Check the verification result.43const verification = su.verifications.emailAddress;44if (verification.verifiedFromTheSameClient()) {45setVerified(true);46// If you're handling the verification result from47// another route/component, you should return here.48// See the <MagicLinkVerification/> component as an49// example below.50// If you want to complete the flow on this tab,51// don't return. Check the sign up status instead.52return;53} else if (verification.status === "expired") {54setExpired(true);55}5657if (su.status === "complete") {58// Sign up is complete, we have a session.59// Navigate to the after sign up URL.60setSession(61su.createdSessionId,62() => router.push("/after-sign-up-path"),63);64return;65}66}6768if (expired) {69return (70<div>Magic link has expired</div>71);72}7374if (verified) {75return (76<div>Signed in on other tab</div>77);78}7980return (81<form onSubmit={submit}>82<input83type="email"84value={emailAddress}85onChange={e => setEmailAddress(e.target.value)}86/>87<button type="submit">88Sign up with magic link89</button>90</form>91);92}9394// pages/verification.jsx95// Handle magic link verification results. This is96// the final step in the magic link flow.97function Verification() {98const [99verificationStatus,100setVerificationStatus,101] = React.useState("loading");102103const { handleMagicLinkVerification } = useClerk();104105React.useEffect(() => {106async function verify() {107try {108await handleMagicLinkVerification({109redirectUrl: "https://redirect-to-pending-sign-up",110redirectUrlComplete: "https://redirect-when-sign-up-complete",111});112// If we're not redirected at this point, it means113// that the flow has completed on another device.114setVerificationStatus("verified");115} catch (err) {116// Verification has failed.117let status = "failed";118if (isMagicLinkError(err) && err.code === MagicLinkErrorCode.Expired) {119status = "expired";120}121setVerificationStatus(status);122}123}124verify();125}, []);126127if (verificationStatus === "loading") {128return <div>Loading...</div>129}130131if (verificationStatus === "failed") {132return (133<div>Magic link verification failed</div>134);135}136137if (verificationStatus === "expired") {138return (139<div>Magic link expired</div>140);141}142143return (144<div>145Successfully signed up. Return to the original tab to continue.146</div>147);148}
1import React from "react";2import {3BrowserRouter as Router,4Routes,5Route,6useNavigate,7} from 'react-router-dom';8import {9ClerkProvider,10ClerkLoaded,11MagicLinkErrorCode,12isMagicLinkError,13UserButton,14useClerk,15useSignUp,16SignedOut,17SignedIn,18} from '@clerk/clerk-react';1920const frontendApi = process.env.REACT_APP_CLERK_FRONTEND_API;2122function App() {23return (24<Router>25<ClerkProvider frontendApi={frontendApi}>26<Switch>27{/* Root path shows sign up page. */}28<Route29path="/"30element={31<>32<SignedOut>33<SignUpMagicLink />34</SignedOut>35<SignedIn>36<UserButton afterSignOutAllUrl="/" />37</SignedIn>38</>39}40/>4142{/* Define a /verification route that handles magic link result */}43<Route44path="/verification"45element={46<ClerkLoaded>47<MagicLinkVerification />48</ClerkLoaded>49}50/>51</Routes>52</ClerkProvider>53</Router>54);55}5657// Render the sign up form.58// Collect user's email address and send a magic link with which59// they can sign up.60function SignUpMagicLink() {61const [emailAddress, setEmailAddress] = React.useState("");62const [expired, setExpired] = React.useState(false);63const [verified, setVerified] = React.useState(false);64const navigate = useNavigate();65const { signUp, setSession } = useSignUp();6667const { startMagicLinkFlow, cancelMagicLinkFlow } =68signUp.createMagicLinkFlow();6970async function submit(e) {71e.preventDefault();72setExpired(false);73setVerified(false);7475// Start the sign up flow, by collecting76// the user's email address.77await signUp.create({ emailAddress });7879// Start the magic link flow.80// Pass your app URL that users will be navigated81// when they click the magic link from their82// email inbox.83// su will hold the updated sign up object.84const su = await startMagicLinkFlow({85redirectUrl: "https://your-app.domain.com/verification",86});8788// Check the verification result.89const verification = su.verifications.emailAddress;90if (verification.verifiedFromTheSameClient()) {91setVerified(true);92// If you're handling the verification result from93// another route/component, you should return here.94// See the <MagicLinkVerification/> component as an95// example below.96// If you want to complete the flow on this tab,97// don't return. Check the sign up status instead.98return;99} else if (verification.status === "expired") {100setExpired(true);101}102103if (su.status === "complete") {104// Sign up is complete, we have a session.105// Navigate to the after sign up URL.106setSession(107su.createdSessionId,108() => navigate("/after-sign-up-path"),109);110return;111}112}113114if (expired) {115return (116<div>Magic link has expired</div>117);118}119120if (verified) {121return (122<div>Signed in on other tab</div>123);124}125126return (127<form onSubmit={submit}>128<input129type="email"130value={emailAddress}131onChange={e => setEmailAddress(e.target.value)}132/>133<button type="submit">134Sign up with magic link135</button>136</form>137);138}139140// Handle magic link verification results. This is141// the final step in the magic link flow.142function MagicLinkVerification() {143const [144verificationStatus,145setVerificationStatus,146] = React.useState("loading");147148const { handleMagicLinkVerification } = useClerk();149150React.useEffect(() => {151async function verify() {152try {153await handleMagicLinkVerification({154redirectUrl: "https://redirect-to-pending-sign-up",155redirectUrlComplete: "https://redirect-when-sign-up-complete",156});157// If we're not redirected at this point, it means158// that the flow has completed on another device.159setVerificationStatus("verified");160} catch (err) {161// Verification has failed.162let status = "failed";163if (isMagicLinkError(err) && err.code === MagicLinkErrorCode.Expired) {164status = "expired";165}166setVerificationStatus(status);167}168}169verify();170}, []);171172if (verificationStatus === "loading") {173return <div>Loading...</div>174}175176if (verificationStatus === "failed") {177return (178<div>Magic link verification failed</div>179);180}181182if (verificationStatus === "expired") {183return (184<div>Magic link expired</div>185);186}187188return (189<div>190Successfully signed up. Return to the original tab to continue.191</div>192);193}194195export default App;
1const signUp = window.Clerk.client.signUp;2const {3startMagicLinkFlow,4cancelMagicLinkFlow,5} = signUp.createMagicLinkFlow();67const res = await startMagicLinkFlow({8// Pass your app URL that users will be navigated9// when they click the magic link from their10// email inbox.11redirectUrl: "https://redirect-from-email-magic-link"12});13if (res.status === "completed") {14// sign up completed15} else {16// sign up still pending17}18// Cleanup19cancelMagicLinkFlow();
Sign in using a custom flow
Signing users into your application is probably the most popular use case for magic links. Users enter their email address and then click on a link that's delivered to them via email message in order to log in.
The sign-in process can be completed on the same or a different device. For example, users might enter their email address in their desktop browser, but click the sign-in magic link from their mobile phone. The user's email address will still be verified and authentication will proceed.
Let's see all the steps involved in more detail.
- Initiate the sign-in process, by collecting the user's authentication identifier. It must be their email address.
- Start the magic link verification flow. There are two parts to the flow:
- Prepare a verification for the email address by sending an email with a magic link to the user.
- Wait until the magic link is clicked. This is a polling behavior that can be canceled at any time.
- Handle the magic link verification result accordingly. Note that the magic link can be clicked on a different device/browser than the one which initiated the flow.
- The verification was successful so you need to continue with the sign-in flow.
- The verification failed or the magic link has expired.
Clerk provides a highly flexible API that allows you to hook into any of the above steps, while abstracting away all the complexities of a magic link based sign in flow.
1import React from "react";2import { useRouter } from "next/router";3import {4MagicLinkErrorCode,5isMagicLinkError,6useClerk,7useSignIn,8useMagicLink,9} from "@clerk/nextjs";1011// pages/sign-in.jsx12// Render the sign in form.13// Collect user's email address and send a magic link with which14// they can sign in.15function SignIn() {16const [emailAddress, setEmailAddress] = React.useState("");17const [expired, setExpired] = React.useState(false);18const [verified, setVerified] = React.useState(false);19const router = useRouter();20const { setSession } = useClerk();21const signIn = useSignIn();2223const { startMagicLinkFlow } = useMagicLink(signIn);2425async function submit(e) {26e.preventDefault();27setExpired(false);28setVerified(false);2930// Start the sign in flow, by collecting31// the user's email address.32const si = await signIn.create({ identifier: emailAddress });33const { email_address_id } = si.supportedFirstFactors.find(34ff => ff.strategy === "email_link" && ff.safe_identifier === emailAddress35);3637// Start the magic link flow.38// Pass your app URL that users will be navigated39// res will hold the updated sign in object.40const res = await startMagicLinkFlow({41emailAddressId: email_address_id,42redirectUrl: "https://your-app.domain.com/verification",43});4445// Check the verification result.46const verification = res.firstFactorVerification;47if (verification.verifiedFromTheSameClient()) {48setVerified(true);49// If you're handling the verification result from50// another route/component, you should return here.51// See the <Verification/> component as an52// example below.53// If you want to complete the flow on this tab,54// don't return. Simply check the sign in status.55return;56} else if (verification.status === "expired") {57setExpired(true);58}59if (res.status === "complete") {60// Sign in is complete, we have a session.61// Navigate to the after sign in URL.62setSession(63res.createdSessionId,64() => router.push("/after-sign-in-path"),65);66return;67}68}6970if (expired) {71return (72<div>Magic link has expired</div>73);74}7576if (verified) {77return (78<div>Signed in on other tab</div>79);80}8182return (83<form onSubmit={submit}>84<input85type="email"86value={emailAddress}87onChange={e => setEmailAddress(e.target.value)}88/>89<button type="submit">90Sign in with magic link91</button>92</form>93);94}9596// pages/verification.jsx97// Handle magic link verification results. This is98// the final step in the magic link flow.99function Verification() {100const [101verificationStatus,102setVerificationStatus,103] = React.useState("loading");104105const { handleMagicLinkVerification } = useClerk();106107React.useEffect(() => {108async function verify() {109try {110await handleMagicLinkVerification({111redirectUrl: "https://redirect-to-pending-sign-in-like-2fa",112redirectUrlComplete: "https://redirect-when-sign-in-complete",113});114// If we're not redirected at this point, it means115// that the flow has completed on another device.116setVerificationStatus("verified");117} catch (err) {118// Verification has failed.119let status = "failed";120if (isMagicLinkError(err) && err.code === MagicLinkErrorCode.Expired) {121status = "expired";122}123setVerificationStatus(status);124}125}126verify();127}, []);128129if (verificationStatus === "loading") {130return <div>Loading...</div>131}132133if (verificationStatus === "failed") {134return (135<div>Magic link verification failed</div>136);137}138139if (verificationStatus === "expired") {140return (141<div>Magic link expired</div>142);143}144145return (146<div>147Successfully signed in. Return to the original tab to continue.148</div>149);150}
1import React from "react";2import {3BrowserRouter as Router,4Routes,5Route,6useNavigate,7} from "react-router-dom";8import {9ClerkProvider,10ClerkLoaded,11MagicLinkErrorCode,12isMagicLinkError,13UserButton,14useClerk,15useSignIn,16useMagicLink,17} from "@clerk/clerk-react";1819const frontendApi = process.env.REACT_APP_CLERK_FRONTEND_API;2021function App() {22return (23<Router>24<ClerkProvider frontendApi={frontendApi}>25<Routes>26{/* Root path shows sign in page. */}27<Route28path="/"29element={30<>31<SignedOut>32<SignInMagicLink />33</SignedOut>34<SignedIn>35<UserButton afterSignOutAllUrl="/" />36</SignedIn>37</>38}39/>4041{/* Define a /verification route that handles magic link result */}42<Route43path="/verification"44element={45<ClerkLoaded>46<MagicLinkVerification />47</ClerkLoaded>48} />49</Routes>50</ClerkProvider>51</Router>52);53}5455// Render the sign in form.56// Collect user's email address and send a magic link with which57// they can sign in.58function SignInMagicLink() {59const [emailAddress, setEmailAddress] = React.useState("");60const [expired, setExpired] = React.useState(false);61const [verified, setVerified] = React.useState(false);62const navigate = useNavigate();63const { setSession } = useClerk();64const signIn = useSignIn();6566const { startMagicLinkFlow } = useMagicLink(signIn);6768async function submit(e) {69e.preventDefault();70setExpired(false);71setVerified(false);7273// Start the sign in flow, by collecting74// the user's email address.75const si = await signIn.create({ identifier: emailAddress });76const { email_address_id } = si.supportedFirstFactors.find(77ff => ff.strategy === "email_link" && ff.safe_identifier === emailAddress78);7980// Start the magic link flow.81// Pass your app URL that users will be navigated82// res will hold the updated sign in object.83const res = await startMagicLinkFlow({84emailAddressId: email_address_id,85redirectUrl: "https://your-app.domain.com/verification",86});8788// Check the verification result.89const verification = res.firstFactorVerification;90if (verification.verifiedFromTheSameClient()) {91setVerified(true);92// If you're handling the verification result from93// another route/component, you should return here.94// See the <MagicLinkVerification/> component as an95// example below.96// If you want to complete the flow on this tab,97// don't return. Simply check the sign in status.98return;99} else if (verification.status === "expired") {100setExpired(true);101}102if (res.status === "complete") {103// Sign in is complete, we have a session.104// Navigate to the after sign in URL.105setSession(106res.createdSessionId,107() => navigate("/after-sign-in-path"),108);109return;110}111}112113if (expired) {114return (115<div>Magic link has expired</div>116);117}118119if (verified) {120return (121<div>Signed in on other tab</div>122);123}124125return (126<form onSubmit={submit}>127<input128type="email"129value={emailAddress}130onChange={e => setEmailAddress(e.target.value)}131/>132<button type="submit">133Sign in with magic link134</button>135</form>136);137}138139// Handle magic link verification results. This is140// the final step in the magic link flow.141function MagicLinkVerification() {142const [143verificationStatus,144setVerificationStatus,145] = React.useState("loading");146147const { handleMagicLinkVerification } = useClerk();148149React.useEffect(() => {150async function verify() {151try {152await handleMagicLinkVerification({153redirectUrl: "https://redirect-to-pending-sign-in-like-2fa",154redirectUrlComplete: "https://redirect-when-sign-in-complete",155});156// If we're not redirected at this point, it means157// that the flow has completed on another device.158setVerificationStatus("verified");159} catch (err) {160// Verification has failed.161let status = "failed";162if (isMagicLinkError(err) && err.code === MagicLinkErrorCode.Expired) {163status = "expired";164}165setVerificationStatus(status);166}167}168verify();169}, []);170171if (verificationStatus === "loading") {172return <div>Loading...</div>173}174175if (verificationStatus === "failed") {176return (177<div>Magic link verification failed</div>178);179}180181if (verificationStatus === "expired") {182return (183<div>Magic link expired</div>184);185}186187return (188<div>189Successfully signed in. Return to the original tab to continue.190</div>191);192}193194export default App;
1const signIn = window.Clerk.client.signIn;2const {3startMagicLinkFlow,4cancelMagicLinkFlow,5} = signIn.createMagicLinkFlow();67const { email_address_id } = signIn.supportedFirstFactors.find(8ff => ff.strategy === "email_link"9&& ff.safe_identifier === "your-users-email"10);1112// Pass your app URL that users will be navigated13// when they click the magic link from their14// email inbox.15const res = await startMagicLinkFlow({16email_address_id,17redirectUrl: "https://redirect-from-email-magic-link",18});19if (res.status === "completed") {20// sign in completed21} else {22// sign in still pending23}24// Cleanup25cancelMagicLinkFlow();
Email address verification
Magic links can also provide a nice user experience for verifying email addresses that users add when updating their profiles. The flow is similar to one-time code verification, but users need only click on the magic link; there's no need to return to your app.
- Collect the user's email address.
- Start the magic link verification flow. There are two parts to the flow:
- Prepare a verification for the email address by sending an email with a magic link to the user.
- Wait until the magic link is clicked. This is a polling behavior that can be canceled at any time.
- Handle the magic link verification result accordingly. Note that the magic link can be clicked on a different device/browser than the one which initiated the flow.
- The verification was successful.
- The verification failed or the magic link has expired.
Clerk provides a highly flexible API that allows you to hook into any of the above steps while abstracting away all the complexities of a magic link-based email address verification.
1import React from "react";2import { useUser, useMagicLink } from "@clerk/nextjs";34// A page where users can add a new email address.5function NewEmailPage() {6const [email, setEmail] = React.useState('');7const [emailAddress, setEmailAddress] = React.useState(null);8const [verified, setVerified] = React.useState(false);910const user = useUser();1112async function submit(e) {13e.preventDefault();14const res = await user.createEmailAddress({ email });15setEmailAddress(res);16}1718if (emailAddress && !verified) {19return (20<VerifyWithMagicLink21emailAddress={emailAddress}22onVerify={() => setVerified(true)}23/>24);25}2627return (28<form onSubmit={submit}>29<input30type="email"31value={email}32onChange={e => setEmail(e.target.value)}33/>34</form>35);36}3738// A page which verifies email addresses with magic links.39function VerifyWithMagicLink({40emailAddress,41onVerify,42}) {43const { startMagicLinkFlow } = useMagicLink(emailAddress);4445React.useEffect(() => {46verify();47}, []);4849async function verify() {50// Start the magic link flow.51// Pass your app URL that users will be navigated52// when they click the magic link from their53// email inbox.54const res = await startMagicLinkFlow({55redirectUrl: "https://redirect-from-email-magic-link",56});5758// res will hold the updated EmailAddress object.59if (res.verification.status === "verified") {60onVerify();61} else {62// act accordingly63}64}6566return (67<div>68Waiting for verification...69</div>70);71}
1import React from "react";2import { useUser, useMagicLink } from "@clerk/clerk-react";34// A page where users can add a new email address.5function NewEmailPage() {6const [email, setEmail] = React.useState('');7const [emailAddress, setEmailAddress] = React.useState(null);8const [verified, setVerified] = React.useState(false);910const user = useUser();1112async function submit(e) {13e.preventDefault();14const res = await user.createEmailAddress({ email });15setEmailAddress(res);16}1718if (emailAddress && !verified) {19return (20<VerifyWithMagicLink21emailAddress={emailAddress}22onVerify={() => setVerified(true)}23/>24);25}2627return (28<form onSubmit={submit}>29<input30type="email"31value={email}32onChange={e => setEmail(e.target.value)}33/>34</form>35);36}3738// A page which verifies email addresses with magic links.39function VerifyWithMagicLink({40emailAddress,41onVerify,42}) {43const { startMagicLinkFlow } = useMagicLink(emailAddress);4445React.useEffect(() => {46verify();47}, []);4849async function verify() {50// Start the magic link flow.51// Pass your app URL that users will be navigated52// when they click the magic link from their53// email inbox.54const res = await startMagicLinkFlow({55redirectUrl: "https://redirect-from-email-magic-link",56});5758// res will hold the updated EmailAddress object.59if (res.verification.status === "verified") {60onVerify();61} else {62// act accordingly63}64}6566return (67<div>68Waiting for verification...69</div>70);71}
1const user = window.Clerk.user;2const emailAddress = user.emailAddresses[0];3const {4startMagicLinkFlow,5cancelMagicLinkFlow,6} = emailAddress.createMagicLinkFlow();78// Pass your app URL that users will be navigated9// when they click the magic link from their10// email inbox.11const res = await startMagicLinkFlow({12redirectUrl: "https://redirect-from-email-magic-link",13});14if (res.verification.status === "verified") {15// email address was verified16} else {17// email address wasn't verified18}19// Cleanup20cancelMagicLinkFlow();