React components and hooks for Hiyve Identity authentication — login, registration, two-factor authentication, password management, email verification, OAuth 2.1/PKCE clients, MCP tokens, and trusted device management.
npm install @hiyve/react-identity @hiyve/identity-client
npm install react @mui/material @mui/icons-material @emotion/react @emotion/styled @hiyve/utilities
When your Express server uses @hiyve/admin middleware (mountHiyveRoutes), the API key stays server-side and IdentityProvider needs no props:
import { IdentityProvider, AuthFlow } from '@hiyve/react-identity';
function App() {
return (
<IdentityProvider>
<AuthFlow
onAuthenticated={(user) => console.log('Logged in:', user)}
onRegistered={(user) => console.log('Registered:', user)}
/>
</IdentityProvider>
);
}
Requests are proxied through your server at /api/hiyve/identity/*, which injects the API key and forwards to Hiyve Cloud.
If you prefer to connect directly to Hiyve Cloud without a server proxy:
<IdentityProvider apiKey="pk_live_xxx">
<AuthFlow onAuthenticated={handleAuth} />
</IdentityProvider>
Pass tokens from your URL to AuthFlow to show the correct view automatically:
const params = new URLSearchParams(location.search);
<AuthFlow
resetToken={params.get('reset_token') || undefined}
verificationToken={params.get('verify_token') || undefined}
onAuthenticated={handleAuth}
/>
Note: Email verification and TFA are independently configurable per-organization on the server. When email verification is disabled, users are created with
emailVerified: trueand no verification email is sent. When TFA is disabled, login always returns tokens directly. See the Server Integration Guide for configuration details.
Use forms directly with your own routing:
import { IdentityProvider, LoginForm } from '@hiyve/react-identity';
function LoginPage() {
return (
<LoginForm
onSuccess={() => navigate('/dashboard')}
onTfaRequired={() => navigate('/verify')}
onForgotPassword={() => navigate('/forgot-password')}
onRegister={() => navigate('/register')}
/>
);
}
Wrap your application (or the authenticated portion) with IdentityProvider to enable all hooks and components.
| Prop | Type | Default | Description |
|---|---|---|---|
apiKey |
string |
— | API key (pk_live_* or pk_test_*). Required unless baseUrl is set |
baseUrl |
string |
— | Full base URL for proxy mode. When set, requests bypass Hiyve Cloud and go to your server |
environment |
'production' | 'development' |
'production' |
API environment |
basePath |
string |
'/identity/auth' |
Custom API base path (ignored when baseUrl is set) |
tokenStorage |
'localStorage' | 'memory' |
'localStorage' |
Token persistence strategy |
autoRefresh |
boolean |
true |
Refresh tokens before expiry |
refreshBuffer |
number |
300 |
Seconds before expiry to trigger refresh |
timeout |
number |
30000 |
Request timeout in milliseconds |
<IdentityProvider
apiKey="pk_test_xxx"
environment="development"
tokenStorage="memory"
>
<App />
</IdentityProvider>
| Hook | Returns | Description |
|---|---|---|
useIdentity() |
IdentityContextValue |
Full context — throws outside provider |
useUser() |
{ user, isAuthenticated, isLoading, status, refreshUser } |
User data and auth status |
useAuthState() |
{ status, isAuthenticated, isLoading, error, tfaRequired, tfaEvent, clearError } |
Auth lifecycle state |
useAuthActions() |
{ login, register, logout, verifyTfa, resendOtp, ... } |
Auth action methods |
useIdentitySafe() |
IdentityContextValue | null |
Returns null outside provider |
useAuthClient() |
HiyveAuth |
Raw @hiyve/identity-client instance for advanced use |
useProfile() |
{ profile, isLoading, error, updateProfile } |
Authenticated user profile with update capability |
function Profile() {
const { user, isAuthenticated } = useUser();
const { logout } = useAuthActions();
if (!isAuthenticated) return <p>Not logged in</p>;
return <button onClick={logout}>Logout {user?.email}</button>;
}
function Header() {
const identity = useIdentitySafe();
return (
<header>
{identity?.isAuthenticated
? <span>{identity.user?.email}</span>
: <a href="/login">Sign In</a>}
</header>
);
}
function ProfilePage() {
const { profile, isLoading, error, updateProfile } = useProfile();
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<p>Hello, {profile?.name}</p>
<button onClick={() => updateProfile({ name: 'New Name' })}>
Update Name
</button>
</div>
);
}
| Component | Description | Key Props |
|---|---|---|
LoginForm |
Email/password login with password visibility toggle | onSuccess, onTfaRequired, onForgotPassword, onRegister |
RegisterForm |
Registration with password strength indicator | onSuccess, onLogin, requireName |
TfaVerification |
6-digit OTP input with countdown resend timer | onSuccess, onBack, resendCooldown |
PasswordResetRequest |
Request a password reset email | onSuccess, onBack |
PasswordResetForm |
Set new password with reset token | token, onSuccess, onBack |
EmailVerification |
Auto-verify email token on mount | token, email, onSuccess, onContinue |
| Component | Description | Key Props |
|---|---|---|
UserProfile |
Avatar, name, email, verification badge, logout | onLogout, showLogout |
DeviceManagement |
List and revoke trusted devices | onError |
McpTokenManagement |
Create, list, and revoke MCP tokens | availablePermissions, expiryOptions |
OAuthClientManagement |
Create, list, and delete OAuth clients | availableScopes |
State machine that composes all auth forms with automatic transitions between login, register, forgot password, TFA, reset password, and email verification.
| Prop | Type | Default | Description |
|---|---|---|---|
initialView |
AuthFlowView |
'login' |
Starting view |
onAuthenticated |
(user) => void |
— | Called on login or TFA success |
onRegistered |
(user) => void |
— | Called on registration success |
resetToken |
string |
— | Auto-navigates to reset password view |
verificationToken |
string |
— | Auto-navigates to email verification view |
showRegisterLink |
boolean |
true |
Show registration option on login |
All components accept labels, colors, styles, and icons props. Override individual values — unspecified values use defaults.
<LoginForm
labels={{ title: 'Welcome Back', submitButton: 'Log In' }}
colors={{ submitButton: '#6200ea', linkText: '#6200ea' }}
styles={{ borderRadius: 12, maxWidth: 360 }}
icons={{ email: <MyEmailIcon /> }}
/>
Use the exported default* objects to see all available keys:
import { defaultLoginFormLabels, defaultLoginFormColors } from '@hiyve/react-identity';
Use merge* functions for programmatic overrides:
import { mergeLoginFormLabels } from '@hiyve/react-identity';
const labels = mergeLoginFormLabels({ title: 'Welcome' });
| Component | Default | Merge Function |
|---|---|---|
| LoginForm | defaultLoginFormLabels |
mergeLoginFormLabels |
defaultLoginFormColors |
mergeLoginFormColors |
|
defaultLoginFormStyles |
mergeLoginFormStyles |
|
defaultLoginFormIcons |
mergeLoginFormIcons |
|
| RegisterForm | defaultRegisterFormLabels |
mergeRegisterFormLabels |
defaultRegisterFormColors |
mergeRegisterFormColors |
|
defaultRegisterFormStyles |
mergeRegisterFormStyles |
|
defaultRegisterFormIcons |
mergeRegisterFormIcons |
|
| TfaVerification | defaultTfaVerificationLabels |
mergeTfaVerificationLabels |
defaultTfaVerificationColors |
mergeTfaVerificationColors |
|
defaultTfaVerificationStyles |
mergeTfaVerificationStyles |
|
defaultTfaVerificationIcons |
mergeTfaVerificationIcons |
|
| PasswordResetRequest | defaultPasswordResetRequestLabels |
mergePasswordResetRequestLabels |
defaultPasswordResetRequestColors |
mergePasswordResetRequestColors |
|
defaultPasswordResetRequestStyles |
mergePasswordResetRequestStyles |
|
defaultPasswordResetRequestIcons |
mergePasswordResetRequestIcons |
|
| PasswordResetForm | defaultPasswordResetFormLabels |
mergePasswordResetFormLabels |
defaultPasswordResetFormColors |
mergePasswordResetFormColors |
|
defaultPasswordResetFormStyles |
mergePasswordResetFormStyles |
|
defaultPasswordResetFormIcons |
mergePasswordResetFormIcons |
|
| EmailVerification | defaultEmailVerificationLabels |
mergeEmailVerificationLabels |
defaultEmailVerificationColors |
mergeEmailVerificationColors |
|
defaultEmailVerificationStyles |
mergeEmailVerificationStyles |
|
defaultEmailVerificationIcons |
mergeEmailVerificationIcons |
|
| UserProfile | defaultUserProfileLabels |
mergeUserProfileLabels |
defaultUserProfileColors |
mergeUserProfileColors |
|
defaultUserProfileStyles |
mergeUserProfileStyles |
|
defaultUserProfileIcons |
mergeUserProfileIcons |
|
| DeviceManagement | defaultDeviceManagementLabels |
mergeDeviceManagementLabels |
defaultDeviceManagementColors |
mergeDeviceManagementColors |
|
defaultDeviceManagementStyles |
mergeDeviceManagementStyles |
|
defaultDeviceManagementIcons |
mergeDeviceManagementIcons |
|
| McpTokenManagement | defaultMcpTokenManagementLabels |
mergeMcpTokenManagementLabels |
defaultMcpTokenManagementColors |
mergeMcpTokenManagementColors |
|
defaultMcpTokenManagementStyles |
mergeMcpTokenManagementStyles |
|
defaultMcpTokenManagementIcons |
mergeMcpTokenManagementIcons |
|
| OAuthClientManagement | defaultOAuthClientManagementLabels |
mergeOAuthClientManagementLabels |
defaultOAuthClientManagementColors |
mergeOAuthClientManagementColors |
|
defaultOAuthClientManagementStyles |
mergeOAuthClientManagementStyles |
|
defaultOAuthClientManagementIcons |
mergeOAuthClientManagementIcons |
|
| AuthFlow | defaultAuthFlowLabels |
mergeAuthFlowLabels |
defaultAuthFlowColors |
mergeAuthFlowColors |
|
defaultAuthFlowStyles |
mergeAuthFlowStyles |
All components accept an onError callback and also display errors inline with dismissible alerts:
<LoginForm onError={(err) => analytics.track('login_error', { message: err.message })} />
All components accept the MUI sx prop for additional styling:
<LoginForm sx={{ p: 4, border: '1px solid #e0e0e0' }} />
When IdentityProvider is mounted above CloudProvider (from @hiyve/react-intelligence) or HiyveProvider (from @hiyve/react), the authenticated user's email is automatically available to those providers. This allows cloud tokens to be generated for the correct user without passing userId manually.
import { IdentityProvider } from '@hiyve/react-identity';
import { CloudProvider } from '@hiyve/react-intelligence';
import { HiyveProvider } from '@hiyve/react';
// Zero-config: IdentityProvider shares the user email,
// CloudProvider and HiyveProvider auto-generate cloud tokens.
function App() {
return (
<IdentityProvider>
<CloudProvider>
<HiyveProvider generateRoomToken={generateRoomToken}>
<MyApp />
</HiyveProvider>
</CloudProvider>
</IdentityProvider>
);
}
IdentityProvider must wrap all identity components and hooks@hiyve/identity-client must be installed as a peer dependency@hiyve/react must be installed as a peer dependency (for identity bridge context)@hiyve/utilities for avatar helpers in UserProfile
@hiyve/react-identity - React components and hooks for Hiyve Identity