React SDK
@namoidhq/react wraps the JavaScript SDK with a provider, hooks, validated
callback helpers, and Hosted Auth components. This guide requires
@namoidhq/react and @namoidhq/js 3.1.0 or later.
Install
pnpm add @namoidhq/react @namoidhq/js
Add the provider
import { NamoIDProvider } from "@namoidhq/react";
export function App() {
return (
<NamoIDProvider clientId="namoid_client_test_…">
<Routes />
</NamoIDProvider>
);
}
The Client ID is public and selects the application, issuer, environment, and branded Hosted Auth pages. Never place a Client Secret in a React bundle.
Hosted redirect
import { SignIn } from "@namoidhq/react";
<SignIn redirectUri="https://app.example.com/auth/callback" />
The component reads public application configuration, creates a state, nonce,
and PKCE transaction, then opens Hosted Auth. Use HostedAuthButton for a
minimal button with your own surrounding layout.
Complete the callback with the same provider client:
import { completeHostedAuthRedirect, useNamoID } from "@namoidhq/react";
import { useEffect } from "react";
export function AuthCallback() {
const namoid = useNamoID();
useEffect(() => {
void completeHostedAuthRedirect(namoid).then(({ identity }) => {
console.log(identity.sub);
});
}, [namoid]);
return <p>Completing sign-in…</p>;
}
The helper validates state, authorization-response issuer, the signed ID token, nonce, and the UserInfo subject before returning tokens and identity.
Popup button
Register a same-origin popup callback and render
relayHostedAuthPopupCallback() from @namoidhq/js on that route. Then use:
import { HostedAuthPopupButton } from "@namoidhq/react";
<HostedAuthPopupButton
redirectUri={`${window.location.origin}/auth/namoid/popup`}
onSuccess={({ identity }) => console.log(identity.sub)}
onError={(error) => console.error(error)}
>
Sign in
</HostedAuthPopupButton>
This is the same OIDC + PKCE flow in a secondary window. The callback bridge relays only the authorization result.
Drop-in sign-in and modal
NamoIDSignIn reads public application configuration and renders direct actions
for configured social providers and hosted email-code, magic-link, phone-code,
password, and passkey ceremonies.
import { NamoIDSignIn } from "@namoidhq/react";
<NamoIDSignIn
redirectUri={`${window.location.origin}/auth/namoid/popup`}
onComplete={({ identity }) => console.log(identity.sub)}
appearance={{ accent: "#0d684f", radius: 16 }}
/>
For an accessible dialog controlled by your application:
const [open, setOpen] = useState(false);
<button onClick={() => setOpen(true)}>Sign in</button>
<NamoIDSignInModal
open={open}
onOpenChange={setOpen}
redirectUri={`${window.location.origin}/auth/namoid/popup`}
onComplete={() => setOpen(false)}
/>
Use useNamoIDSignIn() for custom markup while retaining the same popup and
redirect-fallback behavior. It can select a configured provider or hosted
method, but credentials and authentication challenges remain inside Hosted
Auth.
Native email OTP preview
useNamoIDNativeEmailOtp() and NamoIDNativeEmailOtpSignIn are guarded
Test-only preview APIs. They are not general Live sign-in components. The SDK
loads NamoID-managed Cloudflare Turnstile configuration and obtains fresh
challenge tokens; customers do not configure the site key or action names.
<NamoIDNativeEmailOtpSignIn
redirectUri={`${window.location.origin}/auth/namoid/popup`}
onComplete={({ identity }) => console.log(identity.sub)}
/>
Other methods, social federation, passkeys, and policy-driven MFA continue
through Hosted Auth. Applications with a restrictive Content Security Policy
must allow https://challenges.cloudflare.com for Turnstile scripts and frames.
See Login delivery modes for the product and security boundary.
Session guidance
The React adapter keeps only short-lived protocol state in sessionStorage.
It does not persist bearer or refresh tokens. Use a confidential
backend-for-frontend such as the Next.js SDK when the application
needs durable sessions or refresh tokens.