@sigid/react
React primitives for SigID browser authentication.
Install
npm install @sigid/client @sigid/react
Provider
Create a browser client with @sigid/client, then inject it into
SigIdProvider:
"use client";
import { createSigIdClient } from "@sigid/client";
import { SigIdProvider } from "@sigid/react";
const sigid = createSigIdClient({
baseURL: "https://auth.example.com",
oauth: {
clientId: "public-client-id",
redirectUri: `${window.location.origin}/oauth/callback`,
scopes: ["openid", "profile", "email"],
},
});
export function Providers({ children }: { children: React.ReactNode }) {
return <SigIdProvider client={sigid}>{children}</SigIdProvider>;
}
UI State
import {
SignedIn,
SignedOut,
SignInButton,
SignOutButton,
useSession,
useUser,
} from "@sigid/react";
export function AccountPanel() {
const { session, isLoading, error, refresh } = useSession();
const { user } = useUser();
if (error) return <p>{error.message}</p>;
return (
<>
<span>{isLoading ? "Checking session" : session ? "Signed in" : "Signed out"}</span>
<SignedOut>
<SignInButton returnTo="/protected">Start hosted login</SignInButton>
</SignedOut>
<SignedIn>
<pre>{JSON.stringify({ user, session: session?.session }, null, 2)}</pre>
<button onClick={() => void refresh()} disabled={isLoading}>
Refresh session
</button>
<SignOutButton>Logout</SignOutButton>
</SignedIn>
</>
);
}
Callback
Keep the callback page explicit so setup and OAuth errors are visible:
"use client";
import { useEffect } from "react";
import { useSigId } from "@sigid/react";
export function CallbackPage() {
const { handleCallback } = useSigId();
useEffect(() => {
void handleCallback();
}, [handleCallback]);
return <p>Completing callback</p>;
}
Protected UI And API Calls
Protected is a client-side UX guard. It does not replace backend
authorization. Protected API routes still need server-side access-token
validation.
import { Protected, SignInButton, useSigId } from "@sigid/react";
function ProtectedContent() {
const { fetchWithAuth } = useSigId();
return (
<button onClick={() => void fetchWithAuth("/api/protected")}>
Call protected API
</button>
);
}
export function ProtectedPage() {
return (
<Protected
signedOut={<SignInButton returnTo="/protected">Start hosted login</SignInButton>}
returnTo="/protected"
>
<ProtectedContent />
</Protected>
);
}
Security Boundary
SigIdProvider exposes safe user/session state, loading flags, errors, and
imperative helpers. It does not put access tokens, refresh tokens, ID tokens,
client secrets, admin/service tokens, webhook secrets, or SCIM tokens into
React state.
Use fetchWithAuth() for API transport. It attaches Bearer or DPoP
authorization headers according to the configured SigIdClient. Do not render,
stringify, log, or store raw tokens in UI state.