Skip to Content
SDKsReact

React SDK (@auris/react)

@auris/react v0.1.0

@auris/react provides React bindings for Auris IAM. It wraps @auris/js with a context provider, hooks for accessing authentication state, permission checks, FGA queries, and organization context — plus pre-built UI components for common patterns.


Installation

npm install @auris/react @auris/js

Both packages are required. @auris/react depends on @auris/js as a peer dependency.


AurisProvider

Wrap your application root (or the subtree that needs authentication) with AurisProvider. It initializes the AurisClient, restores any existing session from storage, and provides the Auris context to all child components.

import { AurisProvider } from '@auris/react' function App() { return ( <AurisProvider domain="auth.yourdomain.com" clientId="app_xxxxx" redirectUri="http://localhost:3000/callback" tenant="my-tenant" storage="localStorage" autoRefresh={true} theme={true} > <YourApp /> </AurisProvider> ) }

Props:

PropTypeRequiredDefaultDescription
domainstringYes—Your Auris tenant domain
clientIdstringYes—Application Client ID
redirectUristringConditional—Callback URL for PKCE flows
tenantstringNo'default'Tenant identifier
storagestring | TokenStoreNo'localStorage'Token storage strategy
autoRefreshbooleanNotrueAuto-refresh tokens before expiry
scopestringNo'openid profile email'OAuth2 scopes to request
themeboolean | { injectCss?: boolean; realm?: string }No—When true, automatically loads the Auris branding theme CSS for the tenant

In a Next.js application, import AurisProvider from @auris/nextjs instead of @auris/react. The Next.js package re-exports all React components and hooks.


Hooks

useAuris()

The primary hook. Returns the full authentication context: current user, loading state, auth methods, and error information.

Methods that operate on the underlying client (handleRedirectCallback, verifyMagicLink, refreshToken, getAccessToken) are not exposed directly on the context — access them via client.

Returns:

interface AurisContextValue { // Client instance — use for methods not on context client: AurisClient // State user: UserInfo | null isLoading: boolean isAuthenticated: boolean error: AurisError | null // Auth methods login: (email: string, password: string) => Promise<AuthResult> signup: (email: string, password: string, options?: SignupOptions) => Promise<AuthResult> logout: (options?: LogoutOptions) => Promise<void> loginWithRedirect: (options?: LoginWithRedirectOptions) => Promise<void> loginWithMagicLink: (email: string) => Promise<void> loginWithSocial: (provider: SocialProvider) => Promise<void> loginWithGovernmentIdp: (idp: string, options?: LoginWithGovernmentIdpOptions) => Promise<void> }

Methods accessible via client:

// Access these through: const { client } = useAuris() client.handleRedirectCallback(): Promise<AuthResult> client.verifyMagicLink(token: string): Promise<AuthResult> client.refreshToken(): Promise<AuthResult> client.getAccessToken(): Promise<string | null>
import { useAuris } from '@auris/react' function UserMenu() { const { user, isLoading, isAuthenticated, loginWithRedirect, logout } = useAuris() if (isLoading) return <div>Loading...</div> if (!isAuthenticated) { return <button onClick={loginWithRedirect}>Sign in</button> } return ( <div> <span>{user.name}</span> <button onClick={() => logout({ returnTo: window.location.origin })}>Sign out</button> </div> ) }

useUser()

A focused hook that returns only the current user and its loading state. Use this when you only need user information and do not need auth methods.

Returns:

interface UseUserResult { user: UserInfo | null isLoading: boolean error: AurisError | null }
import { useUser } from '@auris/react' function Avatar() { const { user, isLoading } = useUser() if (isLoading) return <div className="avatar-skeleton" /> if (!user) return null return ( <img src={user.picture ?? `https://ui-avatars.com/api/?name=${user.name}`} alt={user.name} /> ) }

useAccessToken()

Returns the current access token string. Automatically refreshes the token if it is expired and autoRefresh is enabled.

Returns:

interface UseAccessTokenResult { token: string | null isLoading: boolean }
import { useAccessToken } from '@auris/react' function useAuthenticatedFetch() { const { token } = useAccessToken() return async function fetch(url: string, init?: RequestInit) { return window.fetch(url, { ...init, headers: { ...init?.headers, Authorization: `Bearer ${token}`, }, }) } }

usePermissions(permissions)

Check whether the current user has any or all of the specified permissions. Calls the Auris API once per render cycle when the permission list changes.

Signature:

usePermissions(permissions: string[]): UsePermissionsResult

Returns:

interface UsePermissionsResult { has: (permission: string) => boolean hasAll: boolean // true if user has every permission in the array hasAny: boolean // true if user has at least one permission in the array isLoading: boolean error: AurisError | null }
import { usePermissions } from '@auris/react' function AdminActions() { const { has, hasAny, isLoading } = usePermissions(['manage:users', 'delete:content']) if (isLoading) return <Spinner /> return ( <div> {has('manage:users') && <button>Manage Users</button>} {has('delete:content') && <button>Delete Content</button>} {!hasAny && <p>You do not have permission to perform any admin actions.</p>} </div> ) }

useCheckPermission(permission)

Check a single permission. Returns a boolean result. Simpler than usePermissions() when you only need one check.

Signature:

useCheckPermission(permission: string): UseCheckPermissionResult

Returns:

interface UseCheckPermissionResult { allowed: boolean isLoading: boolean error: AurisError | null }
import { useCheckPermission } from '@auris/react' function DeleteButton({ documentId }: { documentId: string }) { const { allowed, isLoading } = useCheckPermission('delete:documents') if (isLoading || !allowed) return null return ( <button onClick={() => deleteDocument(documentId)}>Delete</button> ) }

useOrganization()

Returns the current organization context for B2B multi-tenant applications. The active organization is resolved from the user’s access token claims.

Returns:

interface UseOrganizationResult { organization: Organization | null members: OrganizationMember[] isLoading: boolean error: AurisError | null } interface Organization { id: string name: string slug: string logoUrl?: string metadata: Record<string, unknown> } interface OrganizationMember { userId: string email: string name: string role: 'OWNER' | 'ADMIN' | 'MEMBER' | 'VIEWER' joinedAt: string }
import { useOrganization } from '@auris/react' function OrgHeader() { const { organization, isLoading } = useOrganization() if (isLoading || !organization) return null return ( <div> {organization.logoUrl && <img src={organization.logoUrl} alt={organization.name} />} <h1>{organization.name}</h1> </div> ) }

useFga()

Access Fine-Grained Authorization checks from a React component. Returns check and listObjects functions backed by @auris/js’s FGA module.

Returns:

interface UseFgaResult { check: (input: FgaCheckInput) => Promise<FgaCheckResult> listObjects: (input: FgaListObjectsInput) => Promise<string[]> isLoading: boolean }
import { useFga } from '@auris/react' import { useUser } from '@auris/react' function DocumentActions({ documentId }: { documentId: string }) { const { user } = useUser() const { check } = useFga() const [canEdit, setCanEdit] = React.useState(false) React.useEffect(() => { if (!user) return check({ objectType: 'document', objectId: documentId, relation: 'editor', subjectType: 'user', subjectId: user.id, }).then((r) => setCanEdit(r.allowed)) }, [user, documentId]) return canEdit ? <button>Edit</button> : null }

All Exported Hooks

HookDescription
useAurisPrimary auth context: user, state, and auth methods
useUserCurrent user and loading state only
useAccessTokenCurrent access token string
usePermissionsCheck multiple permissions at once
useCheckPermissionCheck a single permission
useOrganizationCurrent organization context and members
useFgaFine-Grained Authorization checks
useOrganizationsList all organizations the current user belongs to
useLicenseCurrent license entitlements for the authenticated user
useEntitlementsFeature entitlements resolved from the active license
useAurisAIAccess the Auris AI provider context
useAurisChatStreamStreaming chat interface backed by the Auris AI provider
useAurisEmbedEmbed context for white-label and iframed deployments
useAurisThemeRead and toggle the active Auris branding theme
useAurisThemeContextRaw theme context value (use useAurisTheme unless building a theme provider)

Components

AuthGuard

Wraps a subtree and redirects unauthenticated users to the login page. While authentication state is loading, renders the fallback prop (or nothing).

Props:

PropTypeDefaultDescription
loginUrlstring'/login'URL to redirect unauthenticated users to
fallbackReact.ReactNodenullRendered while authentication state is loading
childrenReact.ReactNode—Content to render for authenticated users
import { AuthGuard } from '@auris/react' // Protect an entire page function ProtectedPage() { return ( <AuthGuard loginUrl="/auth/login" fallback={<PageSkeleton />}> <h1>This content requires authentication</h1> <UserDashboard /> </AuthGuard> ) }

PermissionGate

Conditionally renders its children based on whether the current user has a specified permission. Renders the fallback prop (or nothing) when the permission check fails or is loading.

Props:

PropTypeDefaultDescription
permissionstring—Permission string to check (required)
fallbackReact.ReactNodenullRendered when user lacks the permission
requireAllbooleantrueIf permission is an array, require all (not used for single string)
childrenReact.ReactNode—Rendered when user has the permission
import { PermissionGate } from '@auris/react' function InvoicePage() { return ( <div> <h1>Invoices</h1> <InvoiceList /> <PermissionGate permission="create:invoices" fallback={<p>You do not have permission to create invoices.</p>} > <CreateInvoiceButton /> </PermissionGate> <PermissionGate permission="export:invoices"> <ExportButton /> </PermissionGate> </div> ) }

LoginButton

A pre-built button that calls loginWithRedirect(). Accepts all standard HTML button props plus an optional label override.

import { LoginButton } from '@auris/react' function Header() { return ( <nav> <LoginButton label="Sign in with Auris" className="btn btn-primary" /> </nav> ) }

LogoutButton

A pre-built button that calls logout() with an optional returnTo URL.

import { LogoutButton } from '@auris/react' function UserMenu() { return ( <LogoutButton returnTo={window.location.origin} label="Sign out" className="btn btn-secondary" /> ) }

All Exported Components

ComponentDescription
AuthGuardRedirects unauthenticated users; renders fallback while loading
PermissionGateConditionally renders children based on a permission check
LoginButtonPre-built button that calls loginWithRedirect()
LogoutButtonPre-built button that calls logout()
AurisSignInFull sign-in form with email/password and social options. See component API reference for details.
AurisSignUpFull sign-up/registration form. See component API reference for details.
AurisUserButtonAvatar button that opens a user account menu. See component API reference for details.
AurisUserProfileInline user profile panel for account settings. See component API reference for details.
AurisOrganizationSwitcherDropdown to switch between organizations the user belongs to. See component API reference for details.
AurisThemeProviderContext provider that injects the Auris tenant branding theme. See component API reference for details.
LicenseGateConditionally renders children based on an active license entitlement. See component API reference for details.
AurisAIProviderContext provider for the Auris AI features (chat, completions). See component API reference for details.

Complete Example

A full React SPA with login, protected content, permission gating, and logout:

import React from 'react' import { AurisProvider, AuthGuard, PermissionGate, useAuris, usePermissions } from '@auris/react' // 1. Wrap your app at the root export default function App() { return ( <AurisProvider domain={import.meta.env.VITE_AURIS_DOMAIN} clientId={import.meta.env.VITE_AURIS_CLIENT_ID} redirectUri={`${window.location.origin}/callback`} > <Router> <Route path="/" element={<HomePage />} /> <Route path="/callback" element={<CallbackPage />} /> <Route path="/dashboard" element={<DashboardPage />} /> </Router> </AurisProvider> ) } // 2. Callback page — handles the redirect from Auris function CallbackPage() { const { client } = useAuris() const navigate = useNavigate() React.useEffect(() => { client.handleRedirectCallback().then(() => navigate('/dashboard')) }, []) return <p>Completing sign in...</p> } // 3. Protected dashboard with permission-gated sections function DashboardPage() { return ( <AuthGuard loginUrl="/" fallback={<p>Checking credentials...</p>}> <DashboardContent /> </AuthGuard> ) } function DashboardContent() { const { user, logout } = useAuris() const { has, isLoading } = usePermissions(['view:reports', 'manage:users']) return ( <div> <header> <h1>Dashboard</h1> <span>Signed in as {user?.email}</span> <button onClick={() => logout({ returnTo: window.location.origin })}>Sign out</button> </header> <main> <PermissionGate permission="view:reports"> <ReportsSection /> </PermissionGate> <PermissionGate permission="manage:users" fallback={<p>You need admin access to manage users.</p>} > <UserManagement /> </PermissionGate> </main> </div> ) }