Custom Login UI
Wire AuthInGo actions to your own form components.
"use client"; import { useState } from "react"; import { ArrowRight, AtSign, KeyRound, LogOut } from "lucide-react"; import { useAuth } from "@authingo/react"; import { authClient } from "../lib/auth-client"; const createDemoEmail = () => `demo-${Math.random().toString(36).slice(2, 8)}@authingo.dev`; export function CustomLogin() { const { user, checkSession, logout, error: sessionError } = useAuth(); const [email, setEmail] = useState(createDemoEmail); const [password, setPassword] = useState("password"); const [authError, setAuthError] = useState<string | null>(null); const [isLoading, setIsLoading] = useState(false); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); setIsLoading(true); setAuthError(null); // Demo helper: create the random account first, then use normal sign in. const signUpResult = await authClient.signUp.email({ email, password, name: "AuthInGo Demo", }); const result = await authClient.signIn.email({ email, password }); if (!result.error) { await checkSession(); } else { setAuthError(signUpResult.error?.message ?? result.error.message); } setIsLoading(false); }; if (user) { return ( <section className="auth-panel signed-in"> <div className="panel-band"> <span>session</span> <span>active</span> </div> <h1>Signed in</h1> <p className="muted">Current account</p> <div className="identity-strip"> <span>{user.email}</span> </div> <button className="secondary-button" type="button" onClick={() => logout()}> <LogOut size={16} /> Sign out </button> </section> ); } return ( <section className="auth-panel"> <div className="panel-band"> <span>AuthInGo</span> <span>headless</span> </div> <div className="panel-heading"> <div> <p className="eyebrow">Custom Login UI</p> <h1>Build the form your product needs.</h1> </div> </div> <form className="login-form" onSubmit={handleSubmit}> <label className="field"> <span>Email</span> <div className="field-control"> <AtSign className="field-icon" size={18} /> <input type="email" value={email} onChange={(event) => setEmail(event.target.value)} placeholder="demo@authingo.dev" /> </div> </label> <label className="field"> <span>Password</span> <div className="field-control"> <KeyRound className="field-icon" size={18} /> <input type="password" value={password} onChange={(event) => setPassword(event.target.value)} placeholder="password" /> </div> </label> {authError || sessionError ? ( <p className="error">{authError ?? sessionError}</p> ) : null} <button className="primary-button" type="submit" disabled={isLoading}> <span>{isLoading ? "Creating session" : "Create demo session"}</span> <ArrowRight size={16} /> </button> </form> </section> ); }