The mfa client export provides a singleton API for handling multi-factor authentication operations from the client side. All methods are thin wrappers around fetch calls to server-side MFA routes where the actual business logic executes.
Import
import { mfa } from '@auth0/nextjs-auth0/client' ;
Methods
getAuthenticators
List enrolled MFA authenticators for the current MFA session.
async getAuthenticators ( options : { mfaToken: string }): Promise < Authenticator [] >
Encrypted MFA token received from MfaRequiredError
Array of available authenticators Show Authenticator properties
Type of authenticator (e.g., “otp”, “oob”, “email”)
Example:
'use client' ;
import { mfa } from '@auth0/nextjs-auth0/client' ;
import { useState , useEffect } from 'react' ;
export function AuthenticatorList ({ mfaToken }) {
const [ authenticators , setAuthenticators ] = useState ([]);
useEffect (() => {
mfa . getAuthenticators ({ mfaToken })
. then ( setAuthenticators )
. catch ( console . error );
}, [ mfaToken ]);
return (
< ul >
{ authenticators . map ( auth => (
< li key = {auth. id } > {auth. authenticatorType } </ li >
))}
</ ul >
);
}
Throws:
MfaTokenExpiredError - Token TTL exceeded
MfaTokenInvalidError - Token tampered or malformed
MfaGetAuthenticatorsError - Auth0 API error
challenge
Initiate an MFA challenge (e.g., send SMS code).
async challenge ( options : {
mfaToken: string ;
challengeType : string ;
authenticatorId ?: string ;
}): Promise < ChallengeResponse >
Type of challenge (e.g., “oob” for SMS/email, “otp” for authenticator apps)
Specific authenticator to use (required for some challenge types)
Challenge response object Show ChallengeResponse properties
Out-of-band code (for SMS/email challenges)
Binding method for the challenge
Example:
'use client' ;
import { mfa } from '@auth0/nextjs-auth0/client' ;
async function sendSmsCode ( mfaToken , authenticatorId ) {
const challenge = await mfa . challenge ({
mfaToken ,
challengeType: 'oob' ,
authenticatorId
});
// SMS sent, now collect binding code from user
return challenge . oobCode ;
}
Throws:
MfaTokenExpiredError - Token TTL exceeded
MfaTokenInvalidError - Token tampered or malformed
MfaChallengeError - Auth0 API error
verify
Verify MFA code and complete authentication.
async verify ( options : VerifyMfaOptions ): Promise < MfaVerifyResponse >
The VerifyMfaOptions is a union type that accepts different verification methods:
OTP (TOTP)
OOB (SMS/Email)
Recovery Code
{
mfaToken : string ;
otp : string ;
}
For authenticator app codes (6-digit TOTP codes). {
mfaToken : string ;
oobCode : string ;
bindingCode : string ;
}
For SMS or email verification codes. {
mfaToken : string ;
recoveryCode : string ;
}
For recovery/backup codes.
Token response after successful verification Show MfaVerifyResponse properties
Access token for authenticated user
Refresh token (if configured)
ID token with user claims
Token expiration time in seconds
Example:
'use client' ;
import { mfa } from '@auth0/nextjs-auth0/client' ;
import { useState } from 'react' ;
export function MfaVerification ({ mfaToken }) {
const [ otp , setOtp ] = useState ( '' );
const [ error , setError ] = useState ( null );
async function handleVerify () {
try {
await mfa . verify ({ mfaToken , otp });
window . location . href = '/dashboard' ; // Redirect after success
} catch ( err ) {
setError ( err . message );
}
}
return (
< form onSubmit = { e => { e . preventDefault (); handleVerify (); }} >
< input
value = { otp }
onChange = { e => setOtp ( e . target . value )}
placeholder = "Enter 6-digit code"
/>
< button type = "submit" > Verify </ button >
{ error && < p >{ error }</ p >}
</ form >
);
}
Throws:
MfaTokenExpiredError - Token TTL exceeded
MfaTokenInvalidError - Token tampered or malformed
MfaRequiredError - Additional MFA factor required (chained MFA)
MfaVerifyError - Auth0 API error (wrong code, rate limit, etc.)
If Auth0 returns mfa_required, this indicates chained MFA where multiple factors are required sequentially. The error will contain a new mfa_token for the next factor.
enroll
Enroll a new MFA authenticator.
async enroll ( options : EnrollOptions ): Promise < EnrollmentResponse >
options.authenticatorTypes
Array of authenticator types to enroll (e.g., [“otp”], [“oob”], [“email”])
Phone number for SMS enrollment (required for oob type)
Email address for email enrollment (required for email type)
Enrollment response with authenticator details Show EnrollmentResponse properties
ID of the newly enrolled authenticator
Secret key (for OTP authenticators)
QR code URI for OTP enrollment
Recovery codes (if enabled)
Example:
'use client' ;
import { mfa } from '@auth0/nextjs-auth0/client' ;
import { useState } from 'react' ;
import QRCode from 'qrcode.react' ;
export function EnrollOtp ({ mfaToken }) {
const [ enrollment , setEnrollment ] = useState ( null );
async function handleEnroll () {
const result = await mfa . enroll ({
mfaToken ,
authenticatorTypes: [ 'otp' ]
});
setEnrollment ( result );
}
return enrollment ? (
< div >
< QRCode value = {enrollment. barcodeUri } />
< p > Scan this QR code with your authenticator app </ p >
{enrollment.recoveryCodes && (
<div>
<h3>Recovery Codes</h3>
<ul>
{ enrollment . recoveryCodes . map ( code => (
< li key = { code } > { code } </ li >
))}
</ul>
</div>
)}
</ div >
) : (
< button onClick = { handleEnroll } > Enroll Authenticator </ button >
);
}
Throws:
MfaTokenExpiredError - Token TTL exceeded
MfaTokenInvalidError - Token tampered or malformed
MfaEnrollmentError - Auth0 API error
Usage Pattern
The typical MFA flow using the client API:
Catch MfaRequiredError
When authentication fails with MFA required, extract the mfaToken from the error. try {
await someAuthOperation ();
} catch ( error ) {
if ( error instanceof MfaRequiredError ) {
// Store mfaToken for MFA flow
setMfaToken ( error . mfa_token );
}
}
List available authenticators
const authenticators = await mfa . getAuthenticators ({ mfaToken });
Challenge (if needed)
For SMS/email, initiate a challenge: await mfa . challenge ({
mfaToken ,
challengeType: 'oob' ,
authenticatorId: authenticators [ 0 ]. id
});
Verify
Collect the code from the user and verify: const tokens = await mfa . verify ({ mfaToken , otp: userCode });
// Authentication complete, redirect to protected page
See Also