Fix Passkey buttons not triggering sometimes#2748
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the global Passkey JavaScript companion to make passkey button clicks and conditional-mediation sign-in more reliable across Turbo navigation and dynamically inserted DOM.
Tip
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.
Changes:
- Replaces per-button click bindings with a single delegated document click handler for
[data-passkey]. - Ensures transient UI state is reset on
turbo:before-cache(re-enables disabled passkey buttons, clears error state). - Triggers conditional mediation when a matching form appears using a
MutationObserver+WeakSetguard.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| new MutationObserver((mutations) => { | ||
| for (const { addedNodes } of mutations) { | ||
| for (const node of addedNodes) { | ||
| if (node.nodeType === Node.ELEMENT_NODE) mediateIn(node) | ||
| } | ||
|
|
||
| attemptConditionalMediation() | ||
| } | ||
| } | ||
| }).observe(document.documentElement, { childList: true, subtree: true }) |
There was a problem hiding this comment.
passkey.js is imported globally (via app/javascript/application.js), so this MutationObserver will observe the entire document subtree on every page. That can add overhead on pages that will never render passkey conditional-mediation forms. Consider gating observer setup (or its callback work) behind a cheap precondition like presence of the passkey request-options meta tag / conditional mediation API support, so most pages avoid the observer entirely.
No description provided.