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.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.