Skip to main content

JavaScript SDK

@namoidhq/js is the framework-neutral NamoID client for browsers and modern JavaScript runtimes. This guide requires version 3.2.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​

Do not refresh or retain durable sessions in browser JavaScript. A public SPA cannot protect a Client Secret or long-lived refresh token. Keep browser tokens in memory, use short sessions, and start a fresh authorization flow when the interactive session expires.

Applications that need durable sessions must perform refresh and revocation in a confidential backend. Use the Next.js SDK or call the discovered token and revocation endpoints from trusted server code. Never pass a Client Secret to createNamoIDClient() in a browser bundle.

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.