Registry Index

Search the catalog

Type to search items across every indexed registry, or pick a page.

ComponentReactregistry:ui2 dependencies

Recovery Codes

recovery-codes

The sheet of two-factor backup codes, with the three ways off the screen that people actually use: copy, download as a .txt, and print. Reach for it wherever an account hands someone a set of one-time codes to keep — finishing two-factor or MFA enrolment after scanning the authenticator QR, the "View recovery codes" panel in a security settings page, regenerating a set after a lost phone, passkey and WebAuthn fallback codes, seed or backup phrases handed over once, and the onboarding step that will not let you continue until you confirm you have saved them. Common asks it answers: "recovery codes component", "backup codes UI", "2FA recovery codes react", "MFA backup codes screen", "one-time codes list", "download recovery codes txt", "print backup codes", "copy recovery codes", "GitHub-style recovery codes", "show recovery codes once", "regenerate backup codes UI", "shadcn recovery codes", "strike through used backup code". Official shadcn/ui has nothing for it — no recovery, backup-code, download or print item anywhere in its sixty-odd components — so an agent asked for this screen writes it inline, and the inline version is where the whole thing quietly stops working. Print is the worst of it. Everyone writes onClick={window.print()}, which prints the page rather than the codes: the nav, the sidebar and the rest of the settings form come along, and because a freshly issued set is nearly always shown inside a scrolling dialog, the printed sheet is clipped to whatever part of that dialog happened to be scrolled into view. Half the codes are missing, on paper that looks finished, and nobody finds out until the day they need them. This prints a document of its own instead — a titled, dated sheet with the codes laid out so none of them straddle a page break — through a hidden iframe that is 0x0 rather than display:none (a frame that is not displayed prints a blank page), whose srcdoc is set before insertion so the only load event is the sheet's rather than the initial about:blank, and which is torn down on afterprint rather than on the next line, because print() blocks in Chrome and Firefox but returns immediately in Safari, where removing the frame would cancel a dialog still open. The sheet is stated in black on white on purpose: browsers drop background colours when printing but keep text colours, so a dark-mode card sent to a printer comes out as pale grey on white and is close to unreadable. The download half has its own two: the anchor is put into the document before it is clicked, because Firefox ignores a click on an element outside the tree, and the object URL is revoked afterwards — an un-revoked one keeps its blob, which is to say the recovery codes, alive and addressable for the life of the document — but revoked on a later task, since releasing it in the click's own task cancels the download. The file is written with CRLF endings so Windows editors do not render it as a single line; the clipboard gets plain LF and the bare codes with no heading, because it is being pasted into a password manager's notes field. Spent codes are struck through and, because a line through text is a paint decision that reaches nobody using a screen reader, also labelled in words — and they are left out of every export, since a saved file padded with dead codes is the right length and so is worse than no file at all; the header says how many are left whenever any have been spent. role="list" is put back by hand because Safari drops list semantics from a list-style-none <ul>, which would take away the one number that matters here. Pass codes as plain strings for a fresh set or as {code, used} for a set being reviewed later; onExport fires on copy, download or print, which is the signal to unlock your "I have saved these" button. normalizeCodes, formatCodesText, buildPrintDocument, downloadTextFile and printDocument are exported for reuse. Nothing renders a date, so it server-renders without a hydration mismatch — the timestamp is taken when a button is pressed. Composes pulld copy-button; every colour is a shadcn token, so it follows light and dark.

Couldn't load the source right now — try refreshing.