Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Social Buttons Login Block for React

A full-height provider-first sign-in page for a photo-sharing app: four hairline rows for Google, GitHub, Apple and Microsoft with a Last used badge that moves, and an email form that opens in place.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Lead with the providers your visitors already use, with this social buttons login block for React with Base UI. It's the sign-in of Lumenroll, a photo-sharing app: the page's side rails run the full height of the screen and one band crosses it between two rules, holding a start-aligned column. Four Buttons share one bordered group on hairlines, Google, GitHub, Apple and Microsoft, each with a two-letter tile in place of a logo and a chevron, and the way you came in last time wears a "Last used" Badge (GitHub when the page loads). Pressing a row moves the badge to it and shows where a real sign-in would go. Under an "or" rule, one Shine Button, the only colored control, opens the email way in: a Field with an Input and another with a Password Input, then its own Sign in button. The page is start-aligned so opening the pair only grows it downward, and "Use a provider instead" closes it again. It's built from Button, Badge, Field, Input, Password Input, Shine Button and Guides, with a CSS entrance only. For consumer apps where one tap beats a password.

FAQ

What happens when I press a provider or sign in, and what stays in the page?

Nothing leaves the page. A provider row shows "Continue with GitHub" with a note that Lumenroll would send you to that provider's own sign-in page, and a Back button; the "Last used" badge moves to the row you pressed. Email sign-in waits under a spinner for less than a second, then shows "You're signed in" and a polite status message says nothing was sent. Reload and GitHub is the last used again, because nothing is remembered. To wire it for real, point each row at your OAuth or OpenID Connect redirect and post the email form to your auth endpoint where the code says so.

How would the Last used badge work in a real product?

Store the method after a successful sign-in, not when a row is pressed, in a first-party cookie or in local storage, and read it when the page renders so the badge is there on the first paint instead of popping in. Here it is a typed constant, LAST_ON_LOAD, and the state moves with each press so you can see the badge travel. Signing in with email moves it to a quiet "Last used on this browser" line under the email button, since email isn't one of the four rows.

Why does the page start near the top and not in the middle?

Opening the email form makes the page taller, and a centered page would move its heading up by half of that. This one is start-aligned, with more room above than the other sign-in pages, so everything above the form stays where it is and the page grows downward. Pressing "Sign in with email" hides the button, shows the two fields and the Sign in button, moves focus to the email field and says so in the polite status message. "Use a provider instead" puts it away and returns focus to the button that opened it.

Why is the Sign in button never disabled?

A disabled button can't explain itself, and keyboard users can't reach it. Pressing Sign in with an empty or malformed email, or no password, marks those fields invalid, writes one sentence under each and moves focus to the first. Typing clears that field's problem. Each field keeps a line for its problem even when there is none, so a problem never pushes the page.

Why two-letter tiles instead of the provider logos, and how do I add one?

A provider's logo comes with its own usage rules, so the block ships a neutral tile with two letters (Go, Gh, Ap, Ms) and says the provider's name in the button. Drop in the official marks from each provider's brand guidelines where the code marks the icon slot. To add a row, add an entry to PROVIDERS with its name, a slug and its two letters; the list, the "Last used" logic and the result all follow.

How does it read on a phone, and with a screen reader?

On a phone the rows show only the provider's name; the words "Continue with" stay in the button's name for screen readers, so each row still reads "Continue with GitHub", followed by "Last used" where it applies. The rows are real buttons in a list named "Sign in with", in the order they appear. The email button is a disclosure: it is named "Sign in with email" and says it controls the pair of fields.

  • Pro

    A full-height sign-in page for a team chat app: the product's mark, Google and GitHub rows with lettermark tiles, an or rule, email and password checked on submit, and one Sign in button with a simulated wait and its result.

  • Pro

    A sign-in shown as a command palette over a drawn sign-in page: Email and password, GitHub, Google, SSO and Magic link on the keys 1 to 5, plus Create account and Reset password, filtered as you type.

  • Pro

    Recent Accounts Login

    Account choosers

    An account chooser: three recent accounts as hairline rows with initials and a session state, Remove with a permanent Undo, and a password, a plain Continue or an email and password pair under the list.

  • Pro

    Welcome Back Login

    Account choosers

    A full-height returning-user sign-in for a reading tracker: a large initials avatar, Welcome back, Dara, a read-only address and one password field, with a swap to a different account at the same height.

  • Pro

    An 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

    Domain Routing Login

    SSO and providers

    A sign-in page for workforce scheduling that reads the domain of your email and says how that company signs in: one required provider, a provider with a password option, a choice of two, or a password for a stranger.