Getting started
This guide uses @namoidhq/js 3.1.0 or later with a public application in a
Test environment. React applications can use the higher-level
React SDK to complete and validate the same flow.
1. Create a project and application
Sign in at console.namoid.in, create a workspace and project, then select the Test environment.
Create a Browser / SPA application and register the exact callback URL your application will use, for example:
http://localhost:5173/auth/callback
Also register the browser origin when the Console requests one. Copy the Test Client ID. A browser application must not have or use a Client Secret.
2. Configure sign-in
In the same Test environment:
- Enable at least one supported sign-in method.
- Choose whether sign-up or waitlist entry is available.
- Add managed Test users if you want to test email OTP without sending email.
- Open Hosted Auth once from the Console to verify the branding and access mode.
3. Install the SDK
pnpm add @namoidhq/js
import { createNamoIDClient } from "@namoidhq/js";
export const namoid = createNamoIDClient({
clientId: "namoid_client_test_…",
});
The Client ID lets the SDK resolve the correct application, issuer, and Hosted Auth domain. Do not configure an issuer, application ID, or global Hosted Auth URL manually.
4. Start sign-in
Start the flow from a direct user action and keep the one-time transaction only until the callback:
const started = await namoid.hostedAuth.start({
redirectUri: "http://localhost:5173/auth/callback",
});
sessionStorage.setItem(
"namoid_transaction",
JSON.stringify(started.transaction),
);
window.location.assign(started.authorizationUrl);
The SDK creates state, nonce, and an S256 PKCE verifier and discovers the
environment's standard authorization endpoint.
5. Complete the callback
On the registered callback route, verify the returned state before exchanging the single-use authorization code:
const callback = new URL(window.location.href);
const raw = sessionStorage.getItem("namoid_transaction");
const transaction = raw ? JSON.parse(raw) : null;
if (!transaction || callback.searchParams.get("state") !== transaction.state) {
throw new Error("Invalid authorization state");
}
const code = callback.searchParams.get("code");
if (!code) throw new Error("Authorization code is missing");
const tokens = await namoid.hostedAuth.exchangeCode({
code,
redirectUri: transaction.redirectUri,
codeVerifier: transaction.codeVerifier,
});
const identity = await namoid.hostedAuth.userInfo(tokens.access_token);
sessionStorage.removeItem("namoid_transaction");
For production browser applications, prefer @namoidhq/react, which also
validates the response issuer, signed ID token, nonce, and UserInfo subject.
Do not persist bearer or refresh tokens in browser storage. Use a confidential
backend-for-frontend when the application needs a durable session.
6. Test and move to Live
Confirm sign-in, callback validation, application session creation, refresh, and logout in Test. Then create or configure the corresponding Live application with its production callback URL and Live credentials.
Never reuse a Test Client ID in Live.
Runnable examples
The NamoID examples use the same SDK and OIDC contract documented here:
- React SPA for a popup-first public client with redirect fallback.
- Next.js for a confidential backend-for-frontend.
- Express and React for a separate frontend and API server.
- Next.js and Supabase for NamoID authentication with application data in Supabase.