Back to docs

Recipe: Sign-in form patterns

Production-ready sign-in forms with validation, error handling, and loading states. Copy, paste, and adapt to your auth provider.

Email + password

Classic credential form with inline validation and a disabled submit button while loading.

<form className="flex flex-col gap-4">
  <input
    type="email"
    required
    placeholder="you@example.com"
    className="rounded-lg border border-gray-700 bg-transparent px-4 py-3 text-white placeholder-gray-500 focus:border-[#8B5CF6] focus:outline-none"
  />
  <input
    type="password"
    required
    placeholder="Password"
    className="rounded-lg border border-gray-700 bg-transparent px-4 py-3 text-white placeholder-gray-500 focus:border-[#8B5CF6] focus:outline-none"
  />
  <button
    type="submit"
    disabled={loading}
    className="rounded-lg bg-[#8B5CF6] px-4 py-3 font-medium text-white hover:bg-[#7C3AED] disabled:opacity-50 transition-colors"
  >
    {loading ? "Signing in..." : "Sign in"}
  </button>
</form>

OAuth provider buttons

Stacked provider buttons with branded colors and a divider.

<div className="flex flex-col gap-3">
  <button className="flex items-center justify-center gap-3 rounded-lg border border-gray-700 px-4 py-3 text-white hover:border-[#8B5CF6] transition-colors">
    <svg className="h-5 w-5" viewBox="0 0 24 24">...</svg>
    Continue with Google
  </button>
  <button className="flex items-center justify-center gap-3 rounded-lg border border-gray-700 px-4 py-3 text-white hover:border-[#8B5CF6] transition-colors">
    <svg className="h-5 w-5" viewBox="0 0 24 24">...</svg>
    Continue with GitHub
  </button>
</div>

Error display

Show server or client errors above the form with a dismiss button.

{error && (
  <div className="flex items-center justify-between rounded-lg border border-red-500/30 bg-red-500/10 px-4 py-3 text-sm text-red-400">
    <span>{error}</span>
    <button onClick={() => setError(null)} aria-label="Dismiss">
      <svg className="h-4 w-4" viewBox="0 0 24 24">...</svg>
    </button>
  </div>
)}

These patterns are unstyled beyond Tailwind utilities. Drop them into any page and customize spacing, colors, and typography to match your brand.