Optare v1.0 is now available. Get started →
SDKs
React

Frontend SDK: React Hooks

The @optare/optareid-react package provides React hooks and components for authentication.

Installation

npm install @optare/optareid-react @optare/optareid-js

Setup

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