<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().
Minimum usage
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.
Props
Prop | Type | Required | Description |
|---|---|---|---|
|
| yes | The base URL of your IntelliAuth tenant. E.g., |
|
| yes | The application's client id. Visible on the application's detail page in the tenant admin console. |
|
| yes | The URL the browser is sent back to after sign-in. Must be one of the redirect URIs registered on the application. |
|
| no | Space-separated scopes to request. Defaults to |
|
| no | The audience(s) you want in the access token. Defaults to |
|
| no | Where to send the browser after sign-out. Defaults to |
|
| no | Whether to auto-refresh the access token before it expires. Defaults to |
|
| no | Seconds before |
|
| no | Whether to store and use refresh tokens. Defaults to |
|
| no | Callback when a user signs in successfully. |
|
| no | Callback when a user signs out. |
|
| no | Callback when tokens are silently refreshed. |
|
| no | Global error handler. Receives |
|
| no | Where to persist tokens. Defaults to |
The provider must wrap every component that calls useIntelliAuth(). Calling the hook outside the provider throws.
Reading from environment variables
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_).
Single instance
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).
Server-side rendering (SSR)
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.
Lifecycle
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.Render. The
loadingflag istrueuntil bootstrap completes. Render a splash / skeleton during this window.Active. From here,
useris either null (signed out) or populated. The silent-refresh timer runs in the background.Unmount. Rare in production. If it happens, the silent-refresh timer is cleared.
Common pitfalls
Forgetting
redirectUri. The SDK will error at sign-in time; the error mentions the missing prop.Mismatched
redirectUriand 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.