Tutorial

React SPA Integration

Add authentication to any React SPA with the AuthMe SDK — AuthProvider, useAuth hook, ProtectedRoute, and automatic token refresh.

Installation

Terminal
npm install authme-sdk

AuthProvider Setup

Wrap your application root with AuthProvider. It handles token storage, silent refresh, and exposes auth state via context.

src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { AuthProvider } from 'authme-sdk/react';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <AuthProvider
      url={import.meta.env.VITE_AUTHME_URL}
      realm={import.meta.env.VITE_AUTHME_REALM}
      clientId={import.meta.env.VITE_AUTHME_CLIENT_ID}
      redirectUri={window.location.origin + '/callback'}
    >
      <App />
    </AuthProvider>
  </React.StrictMode>
);

useAuth Hook

The useAuth hook gives you access to the current user, auth state, and action functions from any component.

src/components/UserMenu.tsx
import { useAuth } from 'authme-sdk/react';

export function UserMenu() {
  const { user, isAuthenticated, isLoading, login, logout } = useAuth();

  if (isLoading) return <span>Loading…</span>;

  if (!isAuthenticated) {
    return (
      <button onClick={() => login()} className="btn-primary">
        Sign In
      </button>
    );
  }

  return (
    <div className="user-menu">
      <img src={user?.picture} alt={user?.name} />
      <span>{user?.email}</span>
      <button onClick={() => logout()}>Sign Out</button>
    </div>
  );
}

ProtectedRoute Component

Build a wrapper component that redirects unauthenticated users to the login flow.

src/components/ProtectedRoute.tsx
import { useEffect } from 'react';
import { useAuth } from 'authme-sdk/react';

interface Props {
  children: React.ReactNode;
  requiredRole?: string;
}

export function ProtectedRoute({ children, requiredRole }: Props) {
  const { isAuthenticated, isLoading, user, login } = useAuth();

  useEffect(() => {
    if (!isLoading && !isAuthenticated) login();
  }, [isLoading, isAuthenticated]);

  if (isLoading) return <div>Authenticating…</div>;

  if (!isAuthenticated) return null;

  if (requiredRole && !user?.roles?.includes(requiredRole)) {
    return <div>Access denied</div>;
  }

  return <>{children}</>;
}

// Usage in your router:
// <Route path="/dashboard" element={<ProtectedRoute><Dashboard /></ProtectedRoute>} />

Token Management

Use getAccessToken() to attach the access token to outgoing API calls. The SDK automatically refreshes expired tokens.

src/lib/api.ts
import { getAccessToken } from 'authme-sdk/react';

export async function apiFetch(path: string, init?: RequestInit) {
  const token = await getAccessToken(); // refreshes silently if expired

  return fetch(`/api${path}`, {
    ...init,
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
      ...init?.headers,
    },
  });
}