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/jsBoth 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:
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
domain | string | Yes | — | Your Auris tenant domain |
clientId | string | Yes | — | Application Client ID |
redirectUri | string | Conditional | — | Callback URL for PKCE flows |
tenant | string | No | 'default' | Tenant identifier |
storage | string | TokenStore | No | 'localStorage' | Token storage strategy |
autoRefresh | boolean | No | true | Auto-refresh tokens before expiry |
scope | string | No | 'openid profile email' | OAuth2 scopes to request |
theme | boolean | { 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[]): UsePermissionsResultReturns:
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): UseCheckPermissionResultReturns:
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
| Hook | Description |
|---|---|
useAuris | Primary auth context: user, state, and auth methods |
useUser | Current user and loading state only |
useAccessToken | Current access token string |
usePermissions | Check multiple permissions at once |
useCheckPermission | Check a single permission |
useOrganization | Current organization context and members |
useFga | Fine-Grained Authorization checks |
useOrganizations | List all organizations the current user belongs to |
useLicense | Current license entitlements for the authenticated user |
useEntitlements | Feature entitlements resolved from the active license |
useAurisAI | Access the Auris AI provider context |
useAurisChatStream | Streaming chat interface backed by the Auris AI provider |
useAurisEmbed | Embed context for white-label and iframed deployments |
useAurisTheme | Read and toggle the active Auris branding theme |
useAurisThemeContext | Raw 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:
| Prop | Type | Default | Description |
|---|---|---|---|
loginUrl | string | '/login' | URL to redirect unauthenticated users to |
fallback | React.ReactNode | null | Rendered while authentication state is loading |
children | React.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:
| Prop | Type | Default | Description |
|---|---|---|---|
permission | string | — | Permission string to check (required) |
fallback | React.ReactNode | null | Rendered when user lacks the permission |
requireAll | boolean | true | If permission is an array, require all (not used for single string) |
children | React.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
| Component | Description |
|---|---|
AuthGuard | Redirects unauthenticated users; renders fallback while loading |
PermissionGate | Conditionally renders children based on a permission check |
LoginButton | Pre-built button that calls loginWithRedirect() |
LogoutButton | Pre-built button that calls logout() |
AurisSignIn | Full sign-in form with email/password and social options. See component API reference for details. |
AurisSignUp | Full sign-up/registration form. See component API reference for details. |
AurisUserButton | Avatar button that opens a user account menu. See component API reference for details. |
AurisUserProfile | Inline user profile panel for account settings. See component API reference for details. |
AurisOrganizationSwitcher | Dropdown to switch between organizations the user belongs to. See component API reference for details. |
AurisThemeProvider | Context provider that injects the Auris tenant branding theme. See component API reference for details. |
LicenseGate | Conditionally renders children based on an active license entitlement. See component API reference for details. |
AurisAIProvider | Context 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>
)
}Related Pages
- JavaScript SDK — Underlying SDK with full type reference
- Next.js SDK — Server-side helpers and middleware built on @auris/react
- Hosted Login Guide — PKCE flow walkthrough
- Permissions Guide — Role-based access control
- FGA Guide — Fine-Grained Authorization