hundreds-psychiatrist-38730
08/14/2025, 5:42 PM@ory/elements-react
and @ory/nextjs
but without @ory/Elements
but possible simple react-hook-form
brief-egg-61061
08/14/2025, 5:42 PMbrief-egg-61061
08/14/2025, 5:42 PM@ory/elements-react
and @ory/nextjs
for login without Ory Elements components, and specifically with a custom form using react-hook-form
. The official documentation and examples focus on either using Ory Elements components directly, or on building custom UIs using the Ory SDK (@ory/client
) and rendering the login flow UI nodes manually, but they do not show integration with react-hook-form
or a minimal custom form in a Next.js context using @ory/nextjs
and @ory/elements-react
together. If you want to build a custom login form, the recommended approach in the docs is to use the Ory SDK to create and submit login flows, mapping the UI nodes to your own form fields. You can see how to fetch and submit a login flow in React, but not specifically with react-hook-form
or in a Next.js page using @ory/nextjs
helpers. Here is a relevant example for a custom React login form using the Ory SDK, which you could adapt to use with `react-hook-form`: tsx import { Configuration, FrontendApi, LoginFlow, UiNode, UiNodeInputAttributes } from "@ory/client" import { filterNodesByGroups, isUiNodeInputAttributes } from "@ory/integrations/ui" import { useEffect, useState } from "react" import { useSearchParams } from "react-router-dom" const frontend = new FrontendApi( new Configuration({ basePath: "<http://localhost:4000>", // Use your Ory Tunnel or Ory Network URL baseOptions: { withCredentials: true, }, }), ) export const Login = () => { const [flow, setFlow] = useState<LoginFlow>() const [searchParams] = useSearchParams() useEffect(() => { const id = searchParams.get("flow") frontend .getLoginFlow({ id }) .then(({ data: flow }) => setFlow(flow)) .catch((err) => { // handle error }) }, []) const submit = (event: React.FormEvent<HTMLFormElement>) => { event.preventDefault() const form = event.currentTarget const formData = new FormData(form) let body = Object.fromEntries(formData) frontend .updateLoginFlow({ flow: flow.id, updateLoginFlowBody: body, }) .then(() => { // handle success }) .catch((err) => { // handle error }) } const mapUINode = (node: UiNode, key: number) => { if (isUiNodeInputAttributes(node.attributes)) { const attrs = node.attributes as UiNodeInputAttributes if (attrs.type === "submit" || attrs.type === "button") { return ( <button type={attrs.type as "submit" | "reset" | "button" | undefined} name={attrs.name} value={attrs.value} key={key} /> ) } return ( <input name={attrs.name} type={attrs.type} autoComplete={attrs.autocomplete || attrs.name === "identifier" ? "username" : ""} defaultValue={attrs.value} required={attrs.required} disabled={attrs.disabled} key={key} /> ) } } return flow ? ( <form action={flow.ui.action} method={flow.ui.method} onSubmit={submit}> {filterNodesByGroups({ nodes: flow.ui.nodes, groups: ["default", "password"], }).map((node, idx) => mapUINode(node, idx))} </form> ) : ( <div>Loading...</div> ) }
You can adapt this approach to use react-hook-form
by mapping the Ory UI nodes to your form fields and handling submission with `react-hook-form`'s methods, but the knowledge sources do not provide a direct example of this integration. For more details on building a custom UI, see the [Ory Kratos custom UI integration basics](https://www.ory.sh/docs/kratos/bring-your-own-ui/custom-ui-basic-integration#create-login-flow) and [custom UI overview](https://www.ory.sh/docs/kratos/bring-your-own-ui/custom-ui-overview) in the documentation.<br> [Custom UI Integration Basics](https://www.ory.sh/docs/kratos/bring-your-own-ui/custom-ui-basic-integration#create-login-flow)