Split-Screen Sign In

Sign in to your account

Welcome back. Please enter your details.

or continue with email

Don't have an account? Sign up

Everything your team needs, in one place.

Join thousands of teams shipping faster with a workspace built for focus.

  • Unlimited projects and members
  • Enterprise-grade security
  • Real-time collaboration
  • 24/7 priority support
About this block

Split-Screen Sign InPRO

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.

Auth9: Split-Screen Sign In

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.

Upgrade to Pro

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.

Upgrade Now

Installation

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

bash
npx shadcn add "https://ui.beste.co/r/auth9?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
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.

Quick start

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.

tsx
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:

tsx
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: "[email protected]",
        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"
    />
  );
}

Props

PropTypeDefaultDescription
headingstring–Screen title above the form
descriptionstring–Subtext below the heading
socialProvidersSocialProvider[][]Buttons rendered above the divider
labelsAuth9Labels{}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
panelAuth9Panel–Brand panel content; the whole panel column is omitted when not set
panelPosition"left" | "right""right"Which side the brand panel sits on
classNamestring–Extra classes for the outer <section>
ts
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[];
};

Behavior notes

  • The outer grid is always 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.
  • The <form> only calls e.preventDefault() on submit; there is no onSubmit prop, so nothing is actually wired to authenticate.
  • The password show/hide toggle is local useState, swapping the input's type between password and text and the icon between Eye/EyeOff.
  • The remember-me checkbox, the divider, and the submit button each render only when their corresponding labels entry is set, not through separate boolean props.
  • Social provider buttons render as 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.

More Auth blocks

View all Auth
FREE

auth2

Split-Screen Sign Up

PRO

auth32

Editorial Split Sign In

FREE

auth1

Centered Sign In Card

Get Pro access