Two-column sign-in screen pairing a full sign-in form (social providers, email, password with show/hide, remember me) with a brand panel that lists product highlights. Includes a left/right panel position toggle.
Two-column sign-in screen: a full form (social providers, a divider, email and password with show/hide, remember me) on one side, and a brand panel with a heading, description, and a checklist of product highlights on the other. A panelPosition prop flips which side the panel sits on.
Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.
Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.
Radix flavor
npx shadcn add "https://ui.beste.co/r/auth9?email=YOUR_EMAIL&license_key=YOUR_KEY"Base UI flavor
npx shadcn add "https://ui.beste.co/r-base/auth9?email=YOUR_EMAIL&license_key=YOUR_KEY"This installs the block to components/beste/block/auth9.tsx and the button, input, field, and checkbox shadcn/ui primitives it's built on.
The installed file exports auth9Demo alongside the block: the exact props behind the preview above. Spread it to get a working split-screen sign-in in one line.
import { Auth9, auth9Demo } from "@/components/beste/block/auth9";
export default function SignInPage() {
return <Auth9 {...auth9Demo} />;
}Then replace the demo with your own props. Written out, a trimmed setup looks like this:
import { Auth9 } from "@/components/beste/block/auth9";
export default function SignInPage() {
return (
<Auth9
heading="Sign in to your account"
description="Welcome back. Please enter your details."
labels={{
divider: "or continue with email",
email: "Email",
emailPlaceholder: "you@example.com",
password: "Password",
passwordPlaceholder: "Enter your password",
rememberMe: "Remember me",
submit: "Sign in",
passwordToggle: "Toggle password visibility",
}}
forgotPasswordLink={{ label: "Forgot password?", href: "/forgot-password" }}
panel={{
heading: "Everything your team needs, in one place.",
features: ["Unlimited projects", "Enterprise-grade security"],
}}
panelPosition="right"
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
heading | string | – | Screen title above the form |
description | string | – | Subtext below the heading |
socialProviders | SocialProvider[] | [] | Buttons rendered above the divider |
labels | Auth9Labels | {} | Field/button copy, see below |
forgotPasswordLink | { label: string; href: string } | – | Link shown at the right of the password field label |
signupPrompt | { text: string; linkLabel: string; href: string } | – | Line below the form, hidden entirely when not set |
panel | Auth9Panel | – | Brand panel content; the whole panel column is omitted when not set |
panelPosition | "left" | "right" | "right" | Which side the brand panel sits on |
className | string | – | Extra classes for the outer <section> |
type SocialProvider = { label: string; icon: React.ReactNode; href?: string };
type Auth9Labels = {
divider?: string;
email?: string;
emailPlaceholder?: string;
password?: string;
passwordPlaceholder?: string;
rememberMe?: string;
submit?: string;
passwordToggle?: string;
};
type Auth9Panel = {
heading: string;
description?: string;
features?: string[];
};lg:grid-cols-2, whether or not panel is set; if panel is omitted, the form column still only occupies half the width on large screens, leaving the other half blank rather than collapsing to a single column.panelPosition (default "right") is implemented with lg:order-1/lg:order-2 on both the form and panel wrappers, so it only reorders the two columns at the lg breakpoint and above; the brand panel itself is hidden entirely below lg.<form> only calls e.preventDefault() on submit; there is no onSubmit prop, so nothing is actually wired to authenticate.useState, swapping the input's type between password and text and the icon between Eye/EyeOff.labels entry is set, not through separate boolean props.asChild links (next/link) to provider.href, not real OAuth triggers.Wiring the form up
This block ships the form markup only; state, validation, and submit are yours to add. Our guide wires the shadcn Field primitives to React Hook Form, TanStack Form, and Formisch on one field system.
auth2
Two-column registration screen pairing a sign-up form (social providers, name, email, password with show/hide, terms checkbox) with a full-bleed image showcase and customer testimonial. Includes a left/right image position toggle.
auth32
Two-column editorial sign-in pairing an oversized typographic brand panel with a clean email and password form. Stacks the panel above the form on mobile. Perfect for brands that want a minimal, editorial first impression.
auth1
Full-height centered sign-in screen with social login providers, email and password fields, a show/hide password toggle, remember-me checkbox, and forgot-password link. Perfect for SaaS apps, dashboards, and member portals.
auth14
Full-height single sign-on screen with a work-email field, a continue-with-SSO button, and Google and Microsoft providers below a divider. Perfect for B2B and enterprise apps that authenticate via identity providers.
auth6
Full-height passwordless sign-in screen with a single email field, a send-magic-link button, a helper note, and social login providers below a divider. Perfect for passwordless and email-link authentication flows.
auth8
Full-height re-authentication screen showing the signed-in user's avatar, name, and email with a single password field, a forgot-password link, and a use-a-different-account option. Perfect for session unlock and returning-user prompts.