Skip to main content
The UserPasskeyMgmt component lets users enroll and revoke passkeys in a single card-based interface using the My Account API and requires no props to render. The component renders a list of enrolled passkeys, a button to add a new passkey, and a revoke option.

Prerequisites

To enable passkey support:
  • Configure a custom domain on your Auth0 tenant. Passkeys require a custom domain.
  • Enable passkeys on your Auth0 database connection. To learn how to enable passkeys in your Auth0 tenant, read Configure Passkeys.
  • Match origin. The relying party id must equal your application’s domain or be a registrable parent of it. To learn more, read Relying party ID for Passkeys
  • Ensure your application uses HTTPS. WebAuthn requires that your application is served over HTTPS.
  • Install and configure universal components in your application. To install and configure universal components, read Build Account Security UI.

Configure your application

Select your framework to configure environment variables and universal components.

Install the component

pnpm add @auth0/universal-components-react
The install command also adds the @auth0/universal-components-core dependency for shared utilities and Auth0 integration.

Get started

import { UserPasskeyMgmt } from "@auth0/universal-components-react";

export function SecurityPage() {
  return <UserPasskeyMgmt />;
}
  • Components are always imported from the root entry @auth0/universal-components-react, regardless of framework.
  • Only the Auth0ComponentProvider component uses a framework-specific subpath: /spa for React applications, /rwa for Next.js applications.
import React from "react";
import { UserPasskeyMgmt } from "@auth0/universal-components-react";
import { Auth0Provider } from "@auth0/auth0-react";
import { Auth0ComponentProvider } from "@auth0/universal-components-react/spa";
import { analytics } from "./lib/analytics";

function SecurityPage() {
  return (
    <div className="max-w-3xl mx-auto p-6">
      <UserPasskeyMgmt
        addAction={{
          onAfter: () => {
            analytics.track("Passkey Enrolled");
          },
        }}
        revokeAction={{
          onBefore: async (passkey) =>
            confirmDialog(`Remove passkey "${passkey.name}"?`),
          onAfter: (passkey) => {
            analytics.track("Passkey Revoked", { passkeyId: passkey.id });
          },
        }}
        onErrorAction={(error, action) => {
          console.error(`Passkey ${action} failed:`, error.message);
        }}
        customMessages={{
          header: {
            title: "Passkeys",
            description: "Sign in faster and more securely without a password.",
          },
        }}
        styling={{
          variables: {
            light: { "--color-primary": "#4f46e5" },
            dark: { "--color-primary": "#818cf8" },
          },
        }}
      />
    </div>
  );
}

export default function App() {
  const domain = "YOUR_TENANT.auth0.com";
  const clientId = "YOUR_CLIENT_ID";

  return (
    <Auth0Provider
      domain={domain}
      clientId={clientId}
      authorizationParams={{ redirect_uri: window.location.origin }}
      interactiveErrorHandler="popup"
    >
      <Auth0ComponentProvider domain={domain}>
        <SecurityPage />
      </Auth0ComponentProvider>
    </Auth0Provider>
  );
}

Props

Display props

Display props control how the component renders without affecting its behavior.
PropTypeDefaultDescription
hideHeaderbooleanfalseHide the page-level header (title and description). The section card with the passkey list is always shown.

Action props

Action props let you hook into the component’s lifecycle events and trigger or cancel operations.
PropTypeDescription
addActionComponentAction<void>Lifecycle hooks for the add-passkey flow. Set disabled: true to hide the add button.
revokeActionComponentAction<Passkey>Lifecycle hooks for the revoke-passkey flow. Set disabled: true to hide the revoke option.
onFetch() => voidTriggered after the passkey list is successfully loaded.
onErrorAction(error: Error,
action: ‘add’ | ‘revoke’) => void
Triggered when an add or revoke action fails.
addAction Controls the add a passkey flow. onBefore triggers before the browser WebAuthn prompt is shown; return false to cancel (for example, to enforce a passkey limit). onAfter triggers after the new passkey is saved.
  • disabled hide the “Add passkey” button.
  • onBefore() runs before the WebAuthn enrollment ceremony. Return false to cancel.
  • onAfter() runs after the passkey is successfully registered. Use this to refresh session state or send analytics.
<UserPasskeyMgmt
  addAction={{
    onBefore: async () => {
      if (passkeys.length >= 5) {
        toast.error("You can register a maximum of 5 passkeys.");
        return false;
      }
      return true;
    },
    onAfter: () => {
      analytics.track("Passkey Enrolled");
    },
  }}
/>
revokeAction Controls the revoke a passkey flow. The built-in confirmation modal is shown; onBefore runs after the user confirms the modal but before the API call, so you can still cancel at that point. onAfter triggers after the passkey is deleted from the account.
  • disabled hides the revoke option from the passkey actions menu.
  • onBefore(passkey) runs before the revoke API call. Receives the Passkey object. Return false to cancel.
  • onAfter(passkey) runs after the passkey is successfully revoked. Receives the revoked Passkey object.
<UserPasskeyMgmt
  revokeAction={{
    onAfter: (passkey) => {
      auditLog.record({ action: "passkey_revoked", passkeyId: passkey.id });
    },
  }}
/>
onFetch Triggers after the passkey list is successfully loaded on mount. Use this to show or hide adjacent UI that depends on whether the user has any registered passkeys.
<UserPasskeyMgmt
  onFetch={() => {
    setPasskeysLoaded(true);
  }}
/>
onErrorAction Triggers when an add or revoke action fails. The action parameter is 'add' or 'revoke'. Use this to surface errors in your own toast system or error logging service.
<UserPasskeyMgmt
  onErrorAction={(error, action) => {
    console.error(`Passkey ${action} failed:`, error.message);
    toast.error(`Something went wrong while trying to ${action} your passkey.`);
  }}
/>
To render the list read-only, set disabled: true on both actions:
<UserPasskeyMgmt
  addAction={{ disabled: true }}
  revokeAction={{ disabled: true }}
/>

Customize props

Customization props let you adapt copy and styling without modifying source code.
PropTypeDescription
customMessagesPartial<PasskeyMessages>Override default UI text and translations.
stylingComponentStyling<UserPasskeyMgmtClasses>CSS variables and class overrides.
customMessages Customize all text and translations. Every field is optional.
  • headertitle, description (page-level header; hidden when hideHeader is true)
  • Top-level cardsection_title, enabled (badge shown when passkeys are enrolled), no_passkeys (empty state message), add_passkey (add button label)
  • List itemscreated_at (use ${date} as placeholder), last_used (use ${date} as placeholder)
  • Actionsactions.revoke (label in the per-passkey actions menu)
  • Success toastssuccess.add, success.revoke
  • Revoke modalmodals.revoke.title, modals.revoke.consent (use <bold>${name}</bold> to bold the passkey name), modals.revoke.cancel, modals.revoke.confirm
<UserPasskeyMgmt
  customMessages={{
    header: {
      title: "Passkeys",
      description: "Sign in faster and more securely without a password.",
    },
    section_title: "Your passkeys",
    no_passkeys: "No passkeys registered yet.",
    add_passkey: "Add a passkey",
    created_at: "Added ${date}",
    last_used: "Last used ${date}",
    success: {
      add: "Passkey registered successfully.",
      revoke: "Passkey removed.",
    },
    modals: {
      revoke: {
        title: "Remove passkey?",
        consent: "This will permanently remove <bold>${name}</bold>.",
        cancel: "Cancel",
        confirm: "Remove",
      },
    },
  }}
/>
Customize style Customize appearance with CSS variables and class overrides. Supports light/dark themes.
Variables—CSS custom properties
  • common Applied to both themes
  • light Light mode only
  • dark Dark mode only
Class overrides
  • UserPasskeyMgmt-root the outer card container wrapping the passkey list
  • UserPasskeyMgmt-item each individual passkey row card
  • PasskeyActionModal-modalContent the revoke confirmation modal content area
<UserPasskeyMgmt
  styling={{
    variables: {
      light: { "--color-primary": "#4f46e5" },
      dark: { "--color-primary": "#818cf8" },
    },
    classes: {
      "UserPasskeyMgmt-root": "rounded-2xl shadow-md",
      "UserPasskeyMgmt-item": "rounded-xl border border-gray-200",
      "PasskeyActionModal-modalContent": "max-w-sm",
    },
  }}
/>

TypeScript definitions

interface Passkey {
  id: string;
  name?: string;
  createdAt?: string;
  lastUsedAt?: string;
  deviceInfo?: string;
}

interface UserPasskeyMgmtClasses {
  "UserPasskeyMgmt-root"?: string;
  "UserPasskeyMgmt-item"?: string;
  "PasskeyActionModal-modalContent"?: string;
}

// ComponentAction provides before/after hooks and a disabled flag.
// Both hooks receive the same data type T.
interface ComponentAction<T, U = undefined> {
  disabled?: boolean;
  onBefore?: (data: T, extra?: U) => boolean | Promise<boolean>;
  onAfter?: (data: T, extra?: U) => void | Promise<void>;
}

interface UserPasskeyMgmtProps {
  hideHeader?: boolean;
  customMessages?: Partial<PasskeyMessages>;
  styling?: ComponentStyling<UserPasskeyMgmtClasses>;
  addAction?: ComponentAction<void>;
  revokeAction?: ComponentAction<Passkey>;
  onFetch?: () => void;
  onErrorAction?: (error: Error, action: "add" | "revoke") => void;
}

Advanced customization

The UserPasskeyMgmt component is composed of a stateless view component and a hook. Import them individually to build custom workflows.

Available subcomponents

For advanced use cases, you can import individual subcomponents to build custom interfaces.
SubcomponentDescription
UserPasskeyMgmtViewStateless view layer; bring your own data and handlers via useUserPasskey.
PasskeyActionModalThe revoke confirmation modal. Can be rendered standalone if you need a custom revoke trigger separate from the passkey list.

Available hooks

HookDescription
useUserPasskeyFull data and interaction layer: passkey list query, enroll mutation, revoke mutation, modal state, and all event handlers.

Learn more

UserMFAMgmt

Manage MFA factors (TOTP, SMS, email OTP, push, recovery codes) alongside passkeys.

Build a Self-Service Account Security Interface

Overview, prerequisites, and framework setup for all My Account components.