Recipe: Login Dialog
Put the built-in login form inside a browser dialog with one shared provider.
Recipe: a login dialog
Use this when login belongs in a small account panel rather than a separate visual page. The dialog changes presentation; the same Auth actions and server rules still apply.
1import { useRef } from "react"
2import { WpAuthProvider, WpLoginForm } from "@forgewp/auth"
3
4export default function MemberLoginDialog() {
5 const dialog = useRef<HTMLDialogElement>(null)
6 return (
7 <WpAuthProvider>
8 <button type="button" onClick={() => dialog.current?.showModal()}>
9 Sign in
10 </button>
11 <dialog
12 ref={dialog}
13 aria-labelledby="member-login-title"
14 className="rounded-lg p-6"
15 >
16 <h2 id="member-login-title">Sign in to your account</h2>
17 <button type="button" onClick={() => dialog.current?.close()}>
18 Close login
19 </button>
20 <WpLoginForm onSuccess={() => dialog.current?.close()} />
21 </dialog>
22 </WpAuthProvider>
23 )
24}The browser dialog supplies modal behavior and Escape handling. Give each instance a distinct heading ID if the page contains more than one dialog. Add animation in theme CSS only after the keyboard and account workflow works, respecting reduced-motion preferences.
Production login can navigate
Cookie-mode login normally reloads or navigates as part of success. The close callback is useful when the page remains mounted; it is not a guarantee that a successful login stays inside the dialog.
Verify the result
Open the dialog by keyboard, check its accessible heading, close it with the button and Escape, and submit both accepted and rejected credentials. In WordPress, confirm the next page request sees the server session. The dialog itself does not protect private page content.