A comprehensive React SDK for PersonQL authentication and user management. This SDK provides pre-built components, hooks, and utilities to quickly integrate PersonQL authentication into your React applications.
npm install @personql/react
# or
yarn add @personql/react
# or
pnpm add @personql/react
Wrap your app with the PersonQLProvider:
import React from 'react';
import { PersonQLProvider } from '@personql/react';
const config = {
apiUrl: 'https://app.personql.com',
clientId: 'your-client-id',
};
function App() {
return (
<PersonQLProvider config={config}>
<YourAppContent />
</PersonQLProvider>
);
}
import React, { useState } from 'react';
import { SignInForm, SignUpForm, useAuth } from '@personql/react';
function AuthPage() {
const [showSignUp, setShowSignUp] = useState(false);
const { isAuthenticated } = useAuth();
if (isAuthenticated) {
return <Dashboard />;
}
return (
<div className="min-h-screen flex items-center justify-center">
{showSignUp ? (
<SignUpForm
onSuccess={() => console.log('Sign up successful!')}
onSignIn={() => setShowSignUp(false)}
/>
) : (
<SignInForm
onSuccess={() => console.log('Sign in successful!')}
onSignUp={() => setShowSignUp(true)}
/>
)}
</div>
);
}
import React from 'react';
import { AuthGuard } from '@personql/react';
function ProtectedPage() {
return (
<AuthGuard
fallback={<div>Please sign in to access this page</div>}
requireVerification={true}
>
<h1>Protected Content</h1>
<p>Only authenticated and verified users can see this.</p>
</AuthGuard>
);
}
import { SignInForm } from '@personql/react';
<SignInForm
onSuccess={() => navigate('/dashboard')}
onSignUp={() => setShowSignUp(true)}
onForgotPassword={() => setShowForgotPassword(true)}
className="max-w-md mx-auto"
/>;
import { SignUpForm } from '@personql/react';
<SignUpForm
onSuccess={() => navigate('/dashboard')}
onSignIn={() => setShowSignUp(false)}
className="max-w-md mx-auto"
/>;
import { MFAForm } from '@personql/react';
<MFAForm
onSuccess={() => navigate('/dashboard')}
onCancel={() => navigate('/signin')}
/>;
import { ProfileForm } from '@personql/react';
<ProfileForm
onSuccess={() => setShowSuccess(true)}
className="max-w-2xl mx-auto"
/>;
import { AuthGuard } from '@personql/react';
<AuthGuard
fallback={<SignInPrompt />}
redirectTo="/signin"
requireVerification={true}
>
<ProtectedContent />
</AuthGuard>;
Main authentication hook:
import { useAuth } from '@personql/react';
function MyComponent() {
const {
// State
isAuthenticated,
isLoading,
error,
user,
requiresMFA,
mfaMethods,
// Methods
signIn,
signUp,
signOut,
sendMFACode,
verifyMFACode,
forgotPassword,
resetPassword,
clearError,
isSessionExpired,
} = useAuth();
const handleSignIn = async () => {
try {
await signIn({
email: 'user@example.com',
password: 'password123',
rememberMe: true,
});
} catch (error) {
console.error('Sign in failed:', error);
}
};
return (
<div>
{isAuthenticated ? (
<p>Welcome, {user?.firstName}!</p>
) : (
<button onClick={handleSignIn}>Sign In</button>
)}
</div>
);
}
User-specific hook:
import { useUser } from '@personql/react';
function UserProfile() {
const {
// State
user,
isLoading,
error,
// Methods
updateProfile,
refreshUser,
// Computed values
isVerified,
fullName,
initials,
} = useUser();
const handleUpdateProfile = async () => {
await updateProfile({
firstName: 'John',
lastName: 'Doe',
});
};
return (
<div>
<h1>Hello, {fullName}!</h1>
<p>Verification status: {isVerified ? 'Verified' : 'Pending'}</p>
<div className="avatar">{initials}</div>
</div>
);
}
Manage organizations in multi-tenant applications:
import { useOrganization } from '@personql/react';
function MyComponent() {
const {
// State
currentOrganization,
organizations,
loading,
switching,
currentRole,
members,
roles,
// Methods
switchOrganization,
createOrganization,
updateOrganization,
hasPermission,
loadMembers,
loadRoles,
refreshOrganizations,
} = useOrganization();
return (
<div>
<h2>{currentOrganization?.name}</h2>
{hasPermission('users:write') && (
<button>Add Team Member</button>
)}
</div>
);
}
PersonQL React SDK includes built-in support for multi-tenant applications with organizations, roles, and permissions.
Pre-built UI component for switching organizations:
import { OrganizationSwitcher } from '@personql/react';
function Header() {
return (
<header>
<OrganizationSwitcher
onOrganizationChange={(orgId) => {
console.log('Switched to:', orgId);
}}
showCreateButton={true}
onCreateClick={() => setShowCreateModal(true)}
/>
</header>
);
}
import { useOrganization } from '@personql/react';
function AdminPanel() {
const { hasPermission } = useOrganization();
if (!hasPermission('settings:write')) {
return <div>Access Denied</div>;
}
return (
<div>
<h1>Admin Settings</h1>
{/* Admin content */}
</div>
);
}
interface PersonQLConfig {
apiUrl: string; // Your Gateway Worker URL
clientId: string; // Your application client ID
redirectUri?: string; // Redirect URI after auth
scopes?: string[]; // Permission scopes
theme?: Theme; // UI customization
}
interface Theme {
primaryColor?: string;
backgroundColor?: string;
textColor?: string;
borderColor?: string;
borderRadius?: string;
fontFamily?: string;
}
const config = {
apiUrl: 'https://app.personql.com',
clientId: 'your-client-id',
theme: {
primaryColor: '#3b82f6',
backgroundColor: '#ffffff',
textColor: '#1f2937',
borderColor: '#d1d5db',
borderRadius: '0.375rem',
fontFamily: 'Inter, sans-serif',
},
};
<PersonQLProvider config={config}>
<App />
</PersonQLProvider>;
The SDK provides comprehensive error handling:
import { useAuth } from '@personql/react';
function MyComponent() {
const { error, clearError } = useAuth();
if (error) {
return (
<Alert
variant="error"
title={error.code}
message={error.message}
dismissible
onDismiss={clearError}
/>
);
}
return <div>No errors</div>;
}
The SDK is fully typed with TypeScript:
import type {
PersonQLConfig,
AuthState,
User,
SignInCredentials,
SignUpCredentials,
MFACredentials,
AuthError,
Organization,
Role,
OrganizationMember,
} from '@personql/react';