Frontend SDK: React Hooks
The @optare/optareid-react package provides React hooks and components for authentication.
Installation
npm install @optare/optareid-react @optare/optareid-jsSetup
Wrap your app with OptareProvider:
// app/layout.tsx or _app.tsx
import { OptareProvider } from '@optare/optareid-react';
export default function App({ children }) {
return (
<OptareProvider
clientId={process.env.NEXT_PUBLIC_OPTARE_CLIENT_ID}
domain="https://id.optare.one"
>
{children}
</OptareProvider>
);
}Core Hook: useOptare
The main hook for accessing authentication state and methods.
import { useOptare } from '@optare/optareid-react';
function MyComponent() {
const {
user, // Current user or null
isAuthenticated, // Boolean
isLoading, // Boolean
error, // Error or null
login, // () => void - Start OAuth flow
logout, // () => Promise<void>
getAccessToken, // () => Promise<string | null>
} = useOptare();
}User Object
interface User {
id: string;
name: string;
email: string;
image?: string;
emailVerified?: boolean;
}Example: User Profile
import { useOptare } from '@optare/optareid-react';
export function UserProfile() {
const { user, isLoading, isAuthenticated } = useOptare();
if (isLoading) return <div>Loading...</div>;
if (!isAuthenticated) return <div>Please sign in</div>;
return (
<div>
<h2>Welcome, {user?.name}!</h2>
<p>Email: {user?.email}</p>
</div>
);
}Authentication Methods
login()
Initiates OAuth login flow with Optare.
import { useOptare } from '@optare/optareid-react';
function SignInButton() {
const { login, isLoading } = useOptare();
return (
<button onClick={() => login()} disabled={isLoading}>
Sign in with Optare
</button>
);
}logout()
Signs out and clears tokens.
import { useOptare } from '@optare/optareid-react';
function SignOutButton() {
const { logout } = useOptare();
return <button onClick={() => logout()}>Sign Out</button>;
}getAccessToken()
Get the current access token for API calls.
import { useOptare } from '@optare/optareid-react';
function ApiCaller() {
const { getAccessToken } = useOptare();
async function callApi() {
const token = await getAccessToken();
const response = await fetch('/api/protected', {
headers: { Authorization: `Bearer ${token}` }
});
return response.json();
}
}Components
<SignInButton />
Pre-styled sign-in button.
import { SignInButton } from '@optare/optareid-react';
function LoginPage() {
return <SignInButton label="Sign in with Optare" />;
}<LogoutButton />
Pre-styled logout button.
import { LogoutButton } from '@optare/optareid-react';
function Header() {
return <LogoutButton label="Sign Out" />;
}<ProtectedRoute />
Requires authentication to render children.
import { ProtectedRoute } from '@optare/optareid-react';
function Dashboard() {
return (
<ProtectedRoute
loadingComponent={<div>Loading...</div>}
fallback={<div>Please sign in</div>}
>
<h1>Dashboard Content</h1>
</ProtectedRoute>
);
}Common Patterns
Role-Based UI
import { useOptare } from '@optare/optareid-react';
function AdminPanel() {
const { user } = useOptare();
// Assuming role is in token claims
if (user?.role !== 'admin') return null;
return <div>Admin-only content</div>;
}Protected Route Wrapper
import { ProtectedRoute, useOptare } from '@optare/optareid-react';
export default function AdminPage() {
return (
<ProtectedRoute>
<AdminDashboard />
</ProtectedRoute>
);
}Loading States
import { useOptare } from '@optare/optareid-react';
function App() {
const { isLoading, isAuthenticated, user } = useOptare();
if (isLoading) {
return <div className="spinner" />;
}
if (!isAuthenticated) {
return <LoginPage />;
}
return <Dashboard user={user} />;
}TypeScript Support
The SDK is fully typed. All hooks and components have TypeScript definitions.
import { useOptare, User } from '@optare/optareid-react';
function Profile() {
const { user } = useOptare();
// TypeScript knows user is User | null
const displayName: string = user?.name || 'Anonymous';
}Next Steps
- Token Verification - Verify tokens on backend
- Examples - More code examples
- Installation - All SDK packages