Skip to content

React

Wrap your app with AuthProvider and use the useAuth hook to access auth state in any component.

src/auth.ts
import { createAuthClient } from 'authfort-client';

export const auth = createAuthClient({
  baseUrl: '/auth',
  tokenMode: 'cookie',
});
import { createAuthClient } from 'authfort-client';

export const auth = createAuthClient({
  baseUrl: '/auth',
  tokenMode: 'cookie',
});
src/App.tsx
import { AuthProvider } from 'authfort-client/react';
import { auth } from './auth';

function App() {
  return (
    <AuthProvider client={auth}>
      <YourApp />
    </AuthProvider>
  );
}
import { AuthProvider } from 'authfort-client/react';
import { auth } from './auth';

function App() {
  return (
    <AuthProvider client={auth}>
      <YourApp />
    </AuthProvider>
  );
}

AuthProvider provides the client to all child components and automatically calls initialize() to check for an existing session. You do not need to call auth.initialize() manually.

import { useAuth } from 'authfort-client/react';

function Profile() {
  const { state, user, isAuthenticated, isLoading, client } = useAuth();

  if (isLoading) return <p>Loading...</p>;
  if (!isAuthenticated) return <p>Not signed in</p>;

  return (
    <div>
      <p>Hello {user.email}</p>
      <p>Roles: {user.roles.join(', ')}</p>
      <button onClick={() => client.signOut()}>Sign Out</button>
    </div>
  );
}
import { useAuth } from 'authfort-client/react';

function Profile() {
  const { state, user, isAuthenticated, isLoading, client } = useAuth();

  if (isLoading) return <p>Loading...</p>;
  if (!isAuthenticated) return <p>Not signed in</p>;

  return (
    <div>
      <p>Hello {user.email}</p>
      <p>Roles: {user.roles.join(', ')}</p>
      <button onClick={() => client.signOut()}>Sign Out</button>
    </div>
  );
}
FieldTypeDescription
stateAuthState'loading', 'authenticated', or 'unauthenticated'
userAuthUser | nullCurrent user (null if not authenticated)
isAuthenticatedbooleanWhether the user is signed in
isLoadingbooleanWhether initialize() is still running
clientAuthClientThe auth client instance
function LoginPage() {
  const { client } = useAuth();
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    try {
      await client.signIn({ email, password });
      // State updates automatically via AuthProvider
    } catch (err) {
      setError(err.message);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Email" />
      <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Password" />
      <button type="submit">Sign In</button>
      {error && <p>{error}</p>}
    </form>
  );
}
function LoginPage() {
  const { client } = useAuth();
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    try {
      await client.signIn({ email, password });
      // State updates automatically via AuthProvider
    } catch (err) {
      setError(err.message);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Email" />
      <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Password" />
      <button type="submit">Sign In</button>
      {error && <p>{error}</p>}
    </form>
  );
}
function ProtectedRoute({ children }: { children: React.ReactNode }) {
  const { isAuthenticated, isLoading } = useAuth();

  if (isLoading) return <p>Loading...</p>;
  if (!isAuthenticated) return <Navigate to="/login" />;

  return children;
}
function ProtectedRoute({ children }: { children: React.ReactNode }) {
  const { isAuthenticated, isLoading } = useAuth();

  if (isLoading) return <p>Loading...</p>;
  if (!isAuthenticated) return <Navigate to="/login" />;

  return children;
}

Use client.fetch() for authenticated API calls:

function Orders() {
  const { client } = useAuth();
  const [orders, setOrders] = useState([]);

  useEffect(() => {
    client.fetch('/api/orders')
      .then(res => res.json())
      .then(setOrders);
  }, [client]);

  return <ul>{orders.map(o => <li key={o.id}>{o.name}</li>)}</ul>;
}
function Orders() {
  const { client } = useAuth();
  const [orders, setOrders] = useState([]);

  useEffect(() => {
    client.fetch('/api/orders')
      .then(res => res.json())
      .then(setOrders);
  }, [client]);

  return <ul>{orders.map(o => <li key={o.id}>{o.name}</li>)}</ul>;
}