Embedded React
Use thin React components or headless hooks over the same browser session.
The React package uses the same ticket protocol and browser
client as the web components. @arc0/react is prepared
locally and not published. It accepts React 18.3 or React 19 as a peer dependency.
import {
Arc0Provider, Arc0Connect, Arc0Manage, type GetTicket,
} from '@arc0/react';
const getTicket: GetTicket = async ({ browserChallenge, signal }) => {
const response = await fetch('/api/arc0-ticket', {
method: 'POST', signal,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ browserChallenge }),
// Include your application's existing CSRF protection.
});
if (!response.ok) throw new Error('Sign in again');
return response.json();
};
export function ConnectedApps({ userId }: { userId: string }) {
return (
<Arc0Provider key={userId} apiUrl="https://api.arc0.ai"
appUrl="https://app.arc0.ai" getTicket={getTicket}>
<Arc0Connect />
<Arc0Manage />
</Arc0Provider>
);
}Keep the callback stable, and key the provider by your authenticated user identity.
Changing identity or unmounting disposes the old client and cancels pending work.
The backend derives the subject from its own session. Arc0Connections is an alias
for Arc0Manage. Components accept onResult, onError, className and style.
An explicit client prop supports applications managing their own client lifecycle.
Server rendering creates empty hosts; tickets are requested only in the browser.
Headless hooks
Inside Arc0Provider:
useArc0Connect()returns{connect, client, ready}. Callconnect({app})directly in a click handler, before any await, so the popup is allowed by the browser.useArc0Apps()returns{items, loading, error, refresh}.useArc0Connections()returns those fields andrevoke(id). It follows every connection cursor. Require explicit confirmation before calling revoke.
The hooks refresh after client lifecycle changes and discard superseded requests.
No transport, token storage or CSRF implementation is duplicated in React. Errors
are fixed codes such as access_denied, session_expired and popup_blocked.
Use signed lifecycle webhooks for backend decisions; browser results are UI signals.
For an agent-led integration, continue with the coding-agent guide.