Authentication

The sign-in and sign-up pair, shipped as two ready blocks: social providers, an email and password core, and the cross-link to its sibling. Sign-up adds a name field and a live password-strength meter.

Welcome back

Sign in to your account to continue.

Forgot password?

Don't have an account? Sign up

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add auth-form

Usage#

usage.tsxTSX
"use client"import { LoginForm, type AuthProvider, type LoginFormData } from "@/components/ui/auth-form"export function Example() {  async function signIn({ email, password, remember }: LoginFormData) {    await fetch("/api/sign-in", {      method: "POST",      body: JSON.stringify({ email, password, remember }),    })  }  function continueWith(provider: AuthProvider) {    window.location.assign("/api/oauth/" + provider)  }  return <LoginForm onSubmit={signIn} onProvider={continueWith} />}

Sign up#

SignUpForm adds a full-name field and a password-strength meter, and gates the submit on the terms checkbox.

Create your account

Start your free trial. No credit card required.

Use 8+ characters with a mix of letters, numbers & symbols.

Already have an account? Sign in

Provider-first#

ProviderForm drops the password core for a stack of full-width Continue with… buttons: the password-less OAuth pattern. Add showEmail for a magic-link fallback below the providers.

Sign in to Koala

Use a provider or get a magic link by email.

By continuing, you agree to our Terms and Privacy Policy.

Single provider · consent gate

Pass one provider with emphasizeFirst for a single dominant button, and requireTerms to gate it behind a consent checkbox. A social rail links out to the community: the OAuth-only screen used by game servers and Discord-native products.

Want to join Eleven?

Sign in with Discord to request your whitelist and start your story.

Localization#

Every word the three blocks print reads from one labels dictionary, so a translation is written once and handed to all of them. Pass only the keys you change; the rest keep their English defaults. In the two provider phrases, {provider} is replaced with the provider's name wherever your language puts it. The consent sentences carry links whose words move in a translation, so they are whole nodes instead: termsLabel on SignUpForm and ProviderForm. providers picks the social row on LoginForm and SignUpForm too, and the row takes one track per provider.

Hola de nuevo

Entra en tu cuenta para seguir.

¿La has olvidado?

¿No tienes cuenta? Crea una

Full-page screens#

Composed into complete pages, these blocks become the Authentication section family: seven finished sign-in and sign-up screens (split and centered, plus the community Discord screens), each with a full-screen, resizable device-frame preview. For a split screen, drop variant="bare" on the form and place it in a SplitLayout pane so the shell owns the surface; for a centered page, keep the default bordered card on a soft backdrop.

API reference#

LoginForm

Composes Input, Checkbox, and Divider.

  • onSubmit: (data: { email, password, remember }) => void | Promise<void>.
  • onProvider: (provider: "google" | "github" | "apple") => void.
  • variant: "card" (default) or "bare" to embed in a page shell.
  • showSocial (default true), forgotHref, signUpHref.
  • providers: the social row, left to right (default Google, GitHub, Apple).
  • labels: Partial<AuthFormLabels>, the block's strings for a translation.

SignUpForm

Adds a password-strength meter and a terms gate.

  • onSubmit: (data: { name, email, password, acceptedTerms }) => void | Promise<void>.
  • variant ("card" / "bare"), showSocial, signInHref, termsHref, privacyHref.
  • providers, labels (as on LoginForm), and termsLabel to replace the consent sentence whole.

ProviderForm

The password-less provider-first block: a stack of full-width Continue with… buttons with an optional magic-link email and social rail.

  • providers: ("google" | "github" | "apple" | "discord")[] (default the first three).
  • emphasizeFirst renders the first provider as the solid primary button; action sets the verb ("continue" / "sign-in").
  • requireTerms gates every action behind a consent checkbox; termsLabel, termsHref, privacyHref control the copy.
  • showEmail + onSubmit (email: string) => void | Promise<void> add a magic-link field; social renders the community link rail.
  • labels: the button phrase (continueWith or signInWith, following action), the divider, the email field and the rail's name.

FAQ#

LoginForm is the sign-in block with email, password, a "Remember me" checkbox, and a forgot-password link. SignUpForm adds a full-name field and a live password-strength meter, and gates its submit button on the terms checkbox via `acceptedTerms`.