Skip to main content
createCorsairReactClient({ baseURL }) returns a set of typed React hooks built on top of createCorsairClient. One factory call per app, then use the returned hooks anywhere in your component tree.
corsair-client.ts
React 18+ is a peer dependency. If you aren’t on React, use the vanilla client.

Corsair Connect

Wrap your app once. When a Corsair call fails because the tenant hasn’t connected a plugin, a connect dialog opens on its own — there’s no connect UI to build. Two levels of automatic, and you opt into the second only where you want it:
  • The dialog always appears — even for a call you didn’t wrap in anything. The server records a connect-request on every auth-missing failure, and the provider opens the dialog from it.
  • Wrap a mutation in call when you also want it to resume — the action re-runs once connected, with no second click.
Wrap the app at the root and point onConnected at a refresh so server reads that failed re-run against the now-connected account:
app/providers.tsx
baseURL defaults to /api/corsair — set it if your handler is mounted elsewhere. appearance is "light", "dark", or "auto" (the default, which follows the OS color scheme).

Any client call — no wrapper

With just the provider in place, a client-triggered call that fails opens the dialog automatically:
count.tsx
The provider catches the rejection, reads the recorded connect-request, and opens the dialog. It can’t re-run the original call, so the user clicks again after connecting. On by default — set captureUnhandled={false} to turn it off.
In development, Next’s error overlay catches the same rejection and shows on top of the dialog — dismiss it; it’s gone in production. call and error.tsx (below) sidestep it entirely because they catch the error before it is ever unhandled.

Mutations that resume — call

Wrap a mutation in call so the dialog opens and the action re-runs after connect — no second click. It resolves null if the user dismisses the dialog, and rethrows a genuine (non-connect) error:
send.tsx

Read regions — error.tsx

A Server Component that reads Corsair data throws when the tenant isn’t connected. Next routes that render error to the segment’s error.tsx — the only boundary that catches a Server Component throw (a nested client boundary never sees it). Re-export CorsairErrorBoundary there; it opens the dialog and retries the segment once connected:
app/inbox/error.tsx

Proactive connect — connect + isConnected

For a plain “Connect X” button, before anything has failed, connect(plugin) mints a fresh link and opens the same dialog; it resolves true once connected. The same hook reports this user’s live connection status, so the button reflects reality and doesn’t re-prompt an already-connected plugin — status refreshes itself after a successful connect, no manual refetch:
connect-slack.tsx
useConnections() returns { connect, call, isConnected, connections, loading } for the app’s own (default-scope) user. For a multi-tenant admin dashboard reading arbitrary tenants, use the factory’s useConnectionStatus({ tenantId }) instead.
Corsair Connect is React-only — the provider, boundary, and dialog are client components. A non-React frontend still gets the server side: the failed call records a connect-request that you read at /api/corsair/connect/request, so you can build your own prompt or redirect to the connect link. See the vanilla client.

Read hooks

Read hooks follow the same shape:
tenants-list.tsx
Read hooks re-fetch automatically when their argument changes:
tenant-detail.tsx
Available read hooks: useTenants, useTenant(id), usePlugins, usePlugin(id), useConnectionStatus({ tenantId }), usePermission({ id }) or usePermission({ token }).

Mutation hooks

Mutations stay idle until you call mutate(input):
create-tenant.tsx
Available mutation hooks: useCreateTenant, useCreateConnectLink, useOAuthCallback.

Connection status

useConnectionStatus is the hook your dashboard probably opens with. The response is a Record<string, 'connected' | 'missing_credentials' | 'not_connected'> keyed by plugin id:
connections.tsx
For wiring the actual connect-and-authorize flow, see the Connect page.

Escape hatch

If a hook doesn’t fit (e.g. you need imperative access inside an event handler), reach for client:
escape.tsx
It is exactly the vanilla client, sharing the same baseURL.

Scope

These hooks are intentionally minimal: no cache, no deduplication, no request reuse. They give you typed loading/error/data state without forcing a data-layer choice. If you want React Query, SWR, or RTK semantics, build them on top of client.