JavaScript SDK
@namoidhq/js is the framework-neutral NamoID client for browsers and modern
JavaScript runtimes. This guide requires version 3.1.0 or later.
Install
pnpm add @namoidhq/js
Create a client
import { createNamoIDClient } from "@namoidhq/js";
const namoid = createNamoIDClient({
clientId: "namoid_client_test_…",
});
The Client ID resolves the correct application, environment issuer, and Hosted Auth domain. The SDK then uses OpenID Connect discovery instead of hard-coded OAuth endpoints.
The Client ID is public. Do not place a Client Secret in browser code.
Start a hosted redirect
const started = await namoid.hostedAuth.start({
redirectUri: "https://app.example.com/auth/callback",
});
sessionStorage.setItem(
"namoid_transaction",
JSON.stringify(started.transaction),
);
window.location.assign(started.authorizationUrl);
The transaction contains short-lived state, nonce, and PKCE values. Retain it only until the callback; do not store tokens in the same browser storage.
Official SDKs request the ordinary openid profile email identity scopes by
default. Applications normally do not need to specify scopes for sign-in.
Complete a public callback
const transaction = JSON.parse(
sessionStorage.getItem("namoid_transaction")!,
);
const callback = new URL(window.location.href);
if (callback.searchParams.get("state") !== transaction.state) {
throw new Error("Invalid authorization state");
}
const tokens = await namoid.hostedAuth.exchangeCode({
code: callback.searchParams.get("code")!,
redirectUri: transaction.redirectUri,
codeVerifier: transaction.codeVerifier,
});
const identity = await namoid.hostedAuth.userInfo(tokens.access_token);
sessionStorage.removeItem("namoid_transaction");
For browser applications, prefer the React SDK callback helper when possible. It also validates the response issuer, signed ID token, nonce, and UserInfo subject before returning identity.
Open Hosted Auth in a popup
Register a same-origin popup callback such as:
https://app.example.com/auth/namoid/popup
Render the callback bridge on that route:
import { relayHostedAuthPopupCallback } from "@namoidhq/js";
relayHostedAuthPopupCallback();
Then start the popup from a direct user click:
const result = await namoid.hostedAuth.popup({
redirectUri: `${window.location.origin}/auth/namoid/popup`,
});
const tokens = await namoid.hostedAuth.exchangeCode({
code: result.code,
redirectUri: result.transaction.redirectUri,
codeVerifier: result.transaction.codeVerifier,
});
The bridge relays only a bounded authorization response. It never relays tokens,
profile data, credentials, MFA codes, or provider tokens. Handle
popup_blocked, popup_closed, and popup_timeout by offering a fresh hosted
redirect.
Configured hosted methods can be selected without collecting credentials in the application DOM:
await namoid.hostedAuth.popup({
redirectUri: `${window.location.origin}/auth/namoid/popup`,
identityProvider: "google",
});
Use authenticationMethod for a configured hosted passkey, password,
email_otp, magic_link, or phone_otp ceremony.
Public configuration and discovery
const config = await namoid.auth.getConfig();
const discovery = await namoid.auth.getDiscovery();
Public configuration describes the selected application's available pages, sign-in methods, social providers, access mode, branding, support contact, and delivery modes. Discovery is the source of truth for OAuth/OIDC endpoints and capabilities.
Refresh, revocation, and logout
Refresh tokens belong in a confidential backend or another platform-appropriate secure store—not browser storage.
const rotated = await namoid.hostedAuth.refresh({
refreshToken,
clientSecret,
});
await namoid.hostedAuth.revoke({
token: rotated.refresh_token!,
tokenTypeHint: "refresh_token",
clientSecret,
});
To clear the hosted browser session, retain the ID token and build the discovered RP-initiated logout URL:
const logoutUrl = await namoid.hostedAuth.getLogoutUrl({
idTokenHint: idToken,
postLogoutRedirectUri: "https://app.example.com/login",
});
window.location.assign(logoutUrl);
Post-logout destinations must be registered for the application.
Validate an ID token on a server
import { validateOIDCIdToken } from "@namoidhq/js/server";
const claims = await validateOIDCIdToken({
idToken,
discovery,
clientId: namoid.clientId,
nonce: transaction.nonce,
});
For a confidential web application, prefer the Next.js SDK, which validates the callback and keeps application sessions server-side.
Native email OTP preview
The SDK contains a guarded Test-only native email OTP API. It is available only to specifically provisioned public SPA applications and fails closed when the required NamoID-managed human verification or environment policy is absent. See Login delivery modes before using it.
Errors
SDK failures throw NamoIDError, which exposes status, code, and detail
in addition to the normal error message.