Skip to content

<IntelliAuthProvider />

<IntelliAuthProvider /> is the React context that everything else depends on. You mount it once, near the top of the tree, and every component below can call useIntelliAuth().

import { IntelliAuthProvider } from '@intelliauth/react-sdk'
import { createRoot } from 'react-dom/client'
import App from './App'
createRoot(document.getElementById('root')!).render(
<IntelliAuthProvider
tenantUrl="https://banking-cymmetri.intelliauth.local"
clientId="app_01HZX..."
redirectUri={`${window.location.origin}/callback`}
>
<App />
</IntelliAuthProvider>,
)

Three props are required. The rest have sensible defaults.

PropTypeRequiredDescription
tenantUrlstringyesThe base URL of your IntelliAuth tenant. E.g., https://banking-cymmetri.intelliauth.local. No trailing slash.
clientIdstringyesThe application's client id. Visible on the application's detail page in the tenant admin console.
redirectUristringyesThe URL the browser is sent back to after sign-in. Must be one of the redirect URIs registered on the application.
scopestringnoSpace-separated scopes to request. Defaults to openid profile email offline_access.
audiencestring | string[]noThe audience(s) you want in the access token. Defaults to tenantUrl + '/api'.
logoutReturnTostringnoWhere to send the browser after sign-out. Defaults to window.location.origin.
silentRefreshbooleannoWhether to auto-refresh the access token before it expires. Defaults to true.
silentRefreshLeewaynumbernoSeconds before exp to trigger refresh. Defaults to 60.
useRefreshTokensbooleannoWhether to store and use refresh tokens. Defaults to true. If false, silent refresh uses iframe-hosted silent auth instead.
onLogin(user) => voidnoCallback when a user signs in successfully.
onLogout() => voidnoCallback when a user signs out.
onTokenRefresh(tokens) => voidnoCallback when tokens are silently refreshed.
onError(error) => voidnoGlobal error handler. Receives IntelliAuthError instances.
cacheLocation'memory' | 'localstorage'noWhere to persist tokens. Defaults to memory for the access token, an HttpOnly cookie for the refresh token. Setting localstorage makes tokens survive a tab close at the cost of XSS exposure.

The provider must wrap every component that calls useIntelliAuth(). Calling the hook outside the provider throws.

The common pattern is to source the tenant URL and client id from build-time env vars so dev / staging / prod can use different tenants without code changes:

<IntelliAuthProvider
tenantUrl={import.meta.env.VITE_INTELLIAUTH_TENANT_URL!}
clientId={import.meta.env.VITE_INTELLIAUTH_CLIENT_ID!}
redirectUri={`${window.location.origin}/callback`}
>
<App />
</IntelliAuthProvider>

Vite, Next.js, Remix, and similar frameworks all support build-time env vars; check your framework's docs for the right prefix (Vite uses VITE_, Next.js uses NEXT_PUBLIC_).

Mount the provider exactly once. Two providers in the same tree create two independent sessions; they will fight each other on silent refresh and tabs will desync. The provider is designed to live at the root of the app and stay mounted for the app's lifetime.

If you have a portal-mounted modal that needs IntelliAuth, ensure it lives inside the provider's tree (React's createPortal keeps context flowing through the portal — usually fine — but be aware of structure).

For Next.js or Remix, render the provider only on the client. The provider needs window, localStorage, and BroadcastChannel, none of which exist on the server. Two patterns:

  • Wrap the provider in a 'use client' component (Next.js App Router).
  • Render the provider conditionally on typeof window !== 'undefined'.

The user record is still server-renderable if you fetch it server-side via the Node SDK and pass it as initial state; the provider hydrates from there.

  1. Mount. The provider creates an internal AuthClient. If a session cookie is present on the tenant, the client silently bootstraps — it fetches the access token via the silent-auth endpoint, then the user profile.
  2. Render. The loading flag is true until bootstrap completes. Render a splash / skeleton during this window.
  3. Active. From here, user is either null (signed out) or populated. The silent-refresh timer runs in the background.
  4. Unmount. Rare in production. If it happens, the silent-refresh timer is cleared.
  • Forgetting redirectUri. The SDK will error at sign-in time; the error mentions the missing prop.
  • Mismatched redirectUri and the application's registered URI. Down to the trailing slash; whitespace; protocol. Re-check on both sides.
  • Wrapping only a portion of the tree. If a route's component lives outside the provider, useIntelliAuth() throws when that route mounts.
  • Memory vs localstorage cache. Memory is the secure default; switching to localstorage is a trade. Do not switch without understanding the XSS implications.