diff --git a/EXAMPLES.md b/EXAMPLES.md
index e8317742..3c407f9d 100644
--- a/EXAMPLES.md
+++ b/EXAMPLES.md
@@ -13,6 +13,7 @@
- [Connect Accounts for using Token Vault](#connect-accounts-for-using-token-vault)
- [Access SDK Configuration](#access-sdk-configuration)
- [Multi-Factor Authentication (MFA)](#multi-factor-authentication-mfa)
+- [Step-Up Authentication](#step-up-authentication)
## Use with a Class Component
@@ -990,3 +991,82 @@ try {
}
}
```
+
+## Step-Up Authentication
+
+When a protected API requires MFA (step-up authentication), `getAccessTokenSilently` will receive an `mfa_required` error from Auth0. By configuring the `interactiveErrorHandler` option, the SDK can automatically handle this by opening a Universal Login popup for the user to complete MFA, then return the token transparently. No custom MFA UI is required — the entire flow is handled via Auth0's Universal Login.
+
+If you need full control over the MFA experience (custom UI for enrollment, challenge, and verification), see the [Multi-Factor Authentication (MFA)](#multi-factor-authentication-mfa) section instead.
+
+> [!WARNING]
+> This feature only works with the refresh token flow (`useRefreshTokens={true}`) and only handles `mfa_required` errors. Other interactive errors are not intercepted.
+
+### Setup
+
+Configure `Auth0Provider` with `interactiveErrorHandler` set to `"popup"` and refresh tokens enabled:
+
+```jsx
+import { Auth0Provider } from '@auth0/auth0-react';
+
+function App() {
+ return (
+
+
+
+ );
+}
+```
+
+### Usage
+
+With this configuration, `getAccessTokenSilently` automatically opens a popup when the token request triggers an `mfa_required` error. Once the user completes MFA in the popup, the token is returned as if the call succeeded normally:
+
+```jsx
+import React, { useEffect, useState } from 'react';
+import { useAuth0 } from '@auth0/auth0-react';
+
+const ProtectedResource = () => {
+ const { getAccessTokenSilently } = useAuth0();
+ const [data, setData] = useState(null);
+
+ useEffect(() => {
+ (async () => {
+ try {
+ // If MFA is required, a popup opens automatically.
+ // The token is returned after the user completes MFA.
+ const token = await getAccessTokenSilently({
+ authorizationParams: {
+ audience: 'https://api.example.com/',
+ scope: 'read:sensitive',
+ },
+ });
+ const response = await fetch('https://api.example.com/sensitive', {
+ headers: { Authorization: `Bearer ${token}` },
+ });
+ setData(await response.json());
+ } catch (e) {
+ console.error(e);
+ }
+ })();
+ }, [getAccessTokenSilently]);
+
+ if (!data) return
Loading...
;
+ return {JSON.stringify(data)}
;
+};
+
+export default ProtectedResource;
+```
+
+### Error Handling
+
+If the popup is blocked, cancelled, or times out, `getAccessTokenSilently` throws `PopupOpenError`, `PopupCancelledError`, or `PopupTimeoutError` respectively. These can be imported from `@auth0/auth0-react`.
+
diff --git a/package-lock.json b/package-lock.json
index 68015728..54da5d94 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,7 @@
"version": "2.14.0",
"license": "MIT",
"dependencies": {
- "@auth0/auth0-spa-js": "^2.15.0"
+ "@auth0/auth0-spa-js": "^2.16.0"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.0.1",
@@ -91,10 +91,9 @@
}
},
"node_modules/@auth0/auth0-spa-js": {
- "version": "2.15.0",
- "resolved": "https://registry.npmjs.org/@auth0/auth0-spa-js/-/auth0-spa-js-2.15.0.tgz",
- "integrity": "sha512-cXv1Isyy4JEc+GxesQPFj3SEbDSnCVQTGiardY9WLSoYTsMMU585Kgm9TJFPJO4dDq3wi+DSJoy3IUcB3rr9nA==",
- "license": "MIT",
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/@auth0/auth0-spa-js/-/auth0-spa-js-2.16.0.tgz",
+ "integrity": "sha512-UTP45NqjC2jVc/WaWh+iYOZt6FajpTJc+3WzljbXBiv2f76wDw4Mt9hW/aShBovsRmvKEIHaCifD3c/Gxmo2ZQ==",
"dependencies": {
"@auth0/auth0-auth-js": "^1.4.0",
"browser-tabs-lock": "^1.2.15",
diff --git a/package.json b/package.json
index 67339e5a..51d095de 100644
--- a/package.json
+++ b/package.json
@@ -95,6 +95,6 @@
"react-dom": "^16.11.0 || ^17 || ^18 || ~19.0.1 || ~19.1.2 || ^19.2.1"
},
"dependencies": {
- "@auth0/auth0-spa-js": "^2.15.0"
+ "@auth0/auth0-spa-js": "^2.16.0"
}
}
diff --git a/src/index.tsx b/src/index.tsx
index 2a9b43ba..4db5b72e 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -35,6 +35,7 @@ export {
MfaRequiredError,
PopupCancelledError,
PopupTimeoutError,
+ PopupOpenError,
AuthenticationError,
MissingRefreshTokenError,
GenericError,
@@ -44,6 +45,7 @@ export {
ConnectAccountRedirectResult,
ResponseType,
ConnectError,
+ type InteractiveErrorHandler,
CustomTokenExchangeOptions,
TokenEndpointResponse,
ClientConfiguration,