Password-to-Passkey Fallback UI Patterns
Passkeys rarely launch into a greenfield: most products carry an existing password base, and the transition period — where some users have passkeys, some have both, and some have neither — is where UX goes wrong. Strand a user with a lost device and no password, or nag them with an upgrade prompt on every visit, and adoption suffers. This page catalogues the coexistence patterns: the upgrade prompt, the dual-path form, cross-device fallback, and the rule that the recovery path stays until a backup exists. It sits under Progressive Enhancement and Passkey Fallback Flows.
Pattern Reference
| Pattern | When to use | Anti-pattern it prevents |
|---|---|---|
| Dual-path sign-in form | Always, during transition | Forcing a single method |
| Post-login upgrade prompt | User has password, no passkey, supported device | Blocking the app behind enrolment |
| Cross-device (hybrid) fallback | Local ceremony fails or no platform authenticator | Dead-ending on a kiosk |
| Backup-before-removal rule | Before hiding the password path | Account lockout on device loss |
| Frequency-capped nudge | Re-prompting non-adopters | Prompt fatigue |
The state diagram below shows the user’s journey from password-only to passkey-primary, with the password path retained until a backup passkey (or recovery method) exists.
Root Cause Analysis (of poor coexistence UX)
1. Removing the password immediately after first enrolment. A single device-bound passkey plus no password equals a lockout the moment the device is lost — connect this to building a passkey account recovery flow.
2. Prompting to upgrade before sign-in. Blocking the app behind enrolment tanks conversion; the prompt belongs after a successful login.
3. No path on a device without a platform authenticator. A kiosk or shared desktop with no biometric dead-ends unless hybrid transport is offered.
4. Unbounded re-prompting. Nagging on every visit trains users to dismiss reflexively.
Step-by-Step Resolution
Step 1 — Dual-path form
Render both methods; let feature detection reveal the passkey affordance (see feature-detecting passkey support).
<form method="post" action="/login">
<input name="username" autocomplete="username webauthn" required />
<button type="button" id="passkey-btn" hidden>Sign in with a passkey</button>
<details>
<summary>Use your password instead</summary>
<input name="password" type="password" autocomplete="current-password" />
<button type="submit">Sign in</button>
</details>
</form>
Step 2 — Post-login, frequency-capped upgrade prompt
async function maybePromptUpgrade(user: { hasPasskey: boolean }) {
const caps = await getCapabilities();
const lastAsked = Number(localStorage.getItem('pk_prompt_at') ?? 0);
const cooldownMs = 14 * 24 * 60 * 60 * 1000; // ask at most every 14 days
if (user.hasPasskey || !caps.api || Date.now() - lastAsked < cooldownMs) return;
localStorage.setItem('pk_prompt_at', String(Date.now()));
showUpgradeSheet(); // "Sign in faster next time — add a passkey"
}
Step 3 — Cross-device fallback on ceremony failure
On NotAllowedError/ConstraintError, present “Use a passkey on another device” (hybrid) alongside the password, rather than an error.
function showFallback({ reason }: { reason: string }) {
document.getElementById('password-path')!.hidden = false;
document.getElementById('use-another-device')!.hidden = false; // triggers a modal get() → QR/hybrid
}
Step 4 — Enforce backup-before-removal
Only hide the password path once the account has two authenticators or a verified recovery method. This is a server-side policy the client reads.
Verification and Testing
Drive the flow in an emulator: register one passkey, confirm the password path is still present; register a second, confirm the “remove password” option unlocks. Assert the upgrade prompt respects the cooldown by advancing the clock in a test. Verify that with JavaScript disabled the <details> password path is fully usable (no passkey affordance required). Simulate NotAllowedError via the DevTools virtual authenticator (cancel the prompt) and confirm the fallback appears rather than an error page.
Pitfalls
1. Lockout by early password removal. Keep the recovery path until a backup exists.
2. Prompt fatigue. Cap the nudge frequency and never gate the app behind it.
3. No kiosk path. Always offer hybrid/cross-device as a fallback.
Related
- Progressive Enhancement and Passkey Fallback Flows — the parent cluster and enhancement order
- Feature-Detecting Passkey and Conditional Mediation Support — the probes that reveal the passkey affordance
- Building a Passkey Account Recovery Flow — the recovery method that must exist before the password is removed