shadcn.io is not affiliated with official shadcn/ui
Magic Link Login Block for React
A full-height passwordless sign-in for a newsletter tool: one email field, then a Check your inbox state with a drawn envelope, a Resend button that really waits 30 seconds, and a way to change the address.
Installation
Overview
Sign people in without a password, with this magic link login block for React with Base UI. It's the sign-in page of Pigeonry, a newsletter tool: the page's side rails run the full height of the screen and one band crosses it between two rules, holding a centred column with the product's mark, a heading and one sentence. A Field holds the email address, checked when the form is sent, and the Shine Button reads "Email me a link", the only colored control. A good press waits a moment and swaps the form, in the same space, for "Check your inbox": a drawn envelope with a tick, the address, an outline "Open mail app" button and a Countdown Button "Resend link" whose label counts 30 seconds down while a fill drains behind it, with "Use a different email" to go back. Nothing is sent, and the page says so. It's built from Field, Input, Button, Countdown Button, Shine Button and Guides, with a CSS entrance only. For newsletters, communities and any product where nobody wants another password.
FAQ
What stays in the page, and how do I send real links?
Everything: the form checks the address, waits 700 ms and shows the inbox state, and a polite status message says "This demo sent nothing". Nothing is emailed and no token exists. In a product, post the address to your auth endpoint where the code says so. The server creates a single-use token that expires soon (15 minutes is common), stores only its hash, and emails a link that carries it. The page that link opens exchanges the token for a session and discards it.
Is the 30-second wait real?
Yes. Pressing Resend link starts the count: the button reads Resend in 30s, ticks down once a second, and a fill drains behind the label, run by a CSS animation whose end is the end of the wait. Pressing it while it counts does nothing, and focus stays on it. The first send starts the same count, so the button is already waiting when the inbox state appears. A real server should enforce its own limit too, since a page's timer can be skipped.
Does the page tell strangers whether an address has an account?
No, and yours shouldn't. The inbox state reads the same for every well-formed address, whether or not an account exists; your server decides quietly whether to send a sign-in link, a sign-up link or nothing. Only a malformed address gets a problem message.
What does Open mail app do?
In the demo it only says that a real link would open your mail app. The web has no way to open the visitor's mail app directly; products usually link to the webmail they can guess from the address's domain, or to a mailto: or app link on a phone. Pick what fits your audience and keep the button a link, not a script.
Why is the button never disabled?
A disabled button can't explain itself and keyboard users can't reach it. Pressing it with an empty or malformed address marks the field invalid, writes one sentence under it and moves focus there. Typing clears the problem, and the field keeps a line for its problem even when there is none, so nothing moves.
Why doesn't the page jump when the state changes?
The form and the inbox share one grid cell, and an unseen copy of the inbox holds its height, so the centred page keeps the heading where it is. The form turns invisible and inert while the inbox shows, so nothing hidden takes focus. Under reduced motion the swap is instant.
Related
- Pro
One-Time Link Login
PasswordlessA split sign-in about the life of a one-time link: the email drawn beside the form, then a Fresh, Used and Expired status strip with a 10-minute timer and demo controls to open the link twice, request a new one or skip to expiry.
- Pro
Passwordless Login
PasswordlessA full-height method picker for a podcast app: four hairline radio rows (email link, passkey, text code, authenticator app), a cell that says what happens next for the chosen way, and one button whose label follows the choice.
- Pro
Email First Sign In Login
Step by stepAn identifier-first sign-in for an invoicing app: one email field, a lookup against two typed accounts, then either the password step with the address kept as a badge or account creation with the address carried over.
- Pro
OTP Verification Login
Codes and approvalsA code step for a parcel locker app: a six-digit field that checks itself on the sixth digit or on a paste, counts wrong codes down from three, and a resend button that waits 30 seconds after it is pressed.
- Pro
Forgot Password Login
Recovery and resetA forgot-password page for a school learning platform that never says whether an account exists, offers the right mail domain when one is a letter off, and resends the link on a 30-second wait.
- Pro
Passkey Login
PasswordlessAn online bank's sign-in page and its passkey chooser shown open over a drawn sign-in screen: two passkeys as radio rows, Cancel and Continue, a verifying step and a signed-in result, with the real dialog behind the Use your passkey button.