# Components

All components must be rendered inside a [`HumanityProvider`](#humanityprovider).

## `HumanityProvider`

The root context provider. Wrap your entire application with it.

```tsx
import { HumanityProvider } from '@humanity-org/react-sdk';

<HumanityProvider
  clientId="hp_xxx"
  redirectUri="https://app.com/callback"
  environment="production"
  storage="memory"
  theme="system"
  onError={(err) => console.error(err)}
>
  <App />
</HumanityProvider>
```

**Props**

<table><thead><tr><th width="126.40234375">Prop</th><th width="317.53125">Type</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td><code>clientId</code></td><td><code>string</code></td><td><strong>required</strong></td><td>Your Humanity application client ID.</td></tr><tr><td><code>redirectUri</code></td><td><code>string</code></td><td><strong>required</strong></td><td>OAuth callback URI registered in the Developer Portal.</td></tr><tr><td><code>environment</code></td><td><p><code>'production'</code> </p><p> <code>'sandbox'</code></p></td><td><code>'production'</code></td><td>Which Humanity API environment to target.</td></tr><tr><td><code>storage</code></td><td><p><code>'memory'</code></p><p><code>'localStorage'</code></p><p><code>'sessionStorage'</code></p></td><td><code>'memory'</code></td><td>Token storage strategy. <code>memory</code> is most secure — tokens are cleared on page refresh.</td></tr><tr><td><code>theme</code></td><td><p><code>'light'</code></p><p><code>'dark'</code></p><p><code>'system'</code></p></td><td><code>'system'</code></td><td>Controls built-in component theming. <code>system</code> follows the OS preference.</td></tr><tr><td><code>baseUrl</code></td><td><code>string</code></td><td>—</td><td>Advanced: override the API base URL (e.g. for proxies or custom environments).</td></tr><tr><td><code>onError</code></td><td><code>(error: HumanityReactError) => void</code></td><td>—</td><td>Global error handler called for any auth or verification error across all child components.</td></tr></tbody></table>

***

## `HumanityConnect`

OAuth login button that handles the full authentication flow.

```tsx
import { HumanityConnect } from '@humanity-org/react-sdk';

<HumanityConnect
  scopes={['openid', 'profile', 'identity:read']}
  mode="popup"
  variant="primary"
  size="md"
  label="Sign in with Humanity"
  onSuccess={(result) => handleLogin(result)}
  onError={(error) => console.error(error)}
/>
```

**Props**

<table><thead><tr><th width="121.734375">Prop</th><th width="329.01171875">Type</th><th width="196.83203125">Default</th><th>Description</th></tr></thead><tbody><tr><td><code>scopes</code></td><td><code>string[]</code></td><td><code>['openid', 'profile']</code></td><td>OAuth scopes to request.</td></tr><tr><td><code>mode</code></td><td><p><code>'popup'</code></p><p><code>'redirect'</code></p></td><td><code>'popup'</code></td><td>OAuth flow type. Use <code>redirect</code> if popups are blocked.</td></tr><tr><td><code>onSuccess</code></td><td><code>(result: AuthResult) => void</code></td><td>—</td><td>Called after successful authentication.</td></tr><tr><td><code>onError</code></td><td><code>(error: HumanityReactError) => void</code></td><td>—</td><td>Called on authentication error.</td></tr><tr><td><code>onLoading</code></td><td><code>(loading: boolean) => void</code></td><td>—</td><td>Called when loading state changes.</td></tr><tr><td><code>variant</code></td><td><p><code>'primary'</code></p><p><code>'secondary'</code></p><p><code>'outline'</code></p></td><td><code>'primary'</code></td><td>Button visual variant.</td></tr><tr><td><code>size</code></td><td><code>'sm' | 'md' | 'lg'</code></td><td><code>'md'</code></td><td>Button size.</td></tr><tr><td><code>label</code></td><td><code>string</code></td><td><code>'Sign in with Humanity'</code></td><td>Button label text.</td></tr><tr><td><code>disabled</code></td><td><code>boolean</code></td><td><code>false</code></td><td>Disable the button.</td></tr><tr><td><code>className</code></td><td><code>string</code></td><td>—</td><td>Additional CSS class.</td></tr><tr><td><code>style</code></td><td><code>React.CSSProperties</code></td><td>—</td><td>Inline styles.</td></tr><tr><td><code>children</code></td><td><code>React.ReactNode</code></td><td>—</td><td>Custom children — replaces default button content.</td></tr></tbody></table>

***

## `HumanityVerify`

One-click verification button for a single preset.

```tsx
import { HumanityVerify } from '@humanity-org/react-sdk';

<HumanityVerify
  preset="ageOver21"
  onVerified={(result) => {
    if (result.verified) grantAccess();
  }}
/>
```

**Props**

<table><thead><tr><th width="125.81640625">Prop</th><th width="337.53125">Type</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td><code>preset</code></td><td><code>string</code></td><td><strong>required</strong></td><td>Preset key to verify (e.g. <code>'ageOver21'</code>, <code>'kycPassed'</code>).</td></tr><tr><td><code>onVerified</code></td><td><code>(result: VerificationResult) => void</code></td><td>—</td><td>Called after verification completes.</td></tr><tr><td><code>onError</code></td><td><code>(error: HumanityReactError) => void</code></td><td>—</td><td>Called on verification error.</td></tr><tr><td><code>label</code></td><td><code>string</code></td><td>—</td><td>Custom button label.</td></tr><tr><td><code>variant</code></td><td><code>'primary' | 'secondary' | 'outline'</code></td><td><code>'primary'</code></td><td>Button visual variant.</td></tr><tr><td><code>size</code></td><td><code>'sm' | 'md' | 'lg'</code></td><td><code>'md'</code></td><td>Button size.</td></tr><tr><td><code>autoVerify</code></td><td><code>boolean</code></td><td><code>false</code></td><td>Trigger verification automatically on mount.</td></tr></tbody></table>

***

## `HumanityGate`

Conditionally renders children when a preset is verified; shows `fallback` otherwise.

```tsx
import { HumanityGate } from '@humanity-org/react-sdk';

<HumanityGate
  preset="kycPassed"
  fallback={<CompleteKYC />}
  loadingFallback={<Spinner />}
>
  <SecureContent />
</HumanityGate>
```

**Multi-preset gate (AND logic):**

```tsx
<HumanityGate
  presets={['ageOver18', 'kycPassed']}
  requireAll={true}
  fallback={<VerificationRequired />}
>
  <RestrictedContent />
</HumanityGate>
```

**Props**

| Prop              | Type              | Default | Description                                                |
| ----------------- | ----------------- | ------- | ---------------------------------------------------------- |
| `preset`          | `string`          | —       | Single preset key. Gate passes when verified.              |
| `presets`         | `string[]`        | —       | Multiple presets. Use with `requireAll` for AND/OR logic.  |
| `requireAll`      | `boolean`         | `true`  | `true`: all presets must pass. `false`: any one is enough. |
| `fallback`        | `React.ReactNode` | —       | Rendered when the gate condition is not met.               |
| `loadingFallback` | `React.ReactNode` | —       | Rendered while verification is in progress.                |

{% hint style="info" %}
Use either `preset` (single) or `presets` (multiple), not both.
{% endhint %}

***

## `HumanityProfile`

Displays the authenticated user's profile with optional verification badges.

```tsx
import { HumanityProfile } from '@humanity-org/react-sdk';

<HumanityProfile
  variant="card"
  showAvatar={true}
  showBadges={true}
  showFields={['email', 'humanity_score']}
/>
```

**Props**

<table><thead><tr><th width="131.25390625">Prop</th><th width="279.78515625">Type</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td><code>variant</code></td><td><code>'card' | 'inline' | 'minimal'</code></td><td><code>'card'</code></td><td>Display variant.</td></tr><tr><td><code>showAvatar</code></td><td><code>boolean</code></td><td><code>true</code></td><td>Show user avatar.</td></tr><tr><td><code>showBadges</code></td><td><code>boolean</code></td><td><code>true</code></td><td>Show verification badges.</td></tr><tr><td><code>showFields</code></td><td><code>string[]</code></td><td>—</td><td>Profile fields to display.</td></tr><tr><td><code>className</code></td><td><code>string</code></td><td>—</td><td>Additional CSS class.</td></tr></tbody></table>

***

## `HumanityErrorBoundary`

React error boundary for catching and displaying errors within the Humanity component tree.

```tsx
import { HumanityErrorBoundary } from '@humanity-org/react-sdk';

<HumanityErrorBoundary
  fallback={(error) => <p>Something went wrong: {error.message}</p>}
  onError={(error, info) => Sentry.captureException(error)}
>
  <HumanityConnect />
</HumanityErrorBoundary>
```

**Props**

<table><thead><tr><th width="126.62890625">Prop</th><th width="405.1796875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>fallback</code></td><td><code>(error: Error) => React.ReactNode</code></td><td>Render function for the error state.</td></tr><tr><td><code>onError</code></td><td><code>(error: Error, info: React.ErrorInfo) => void</code></td><td>Called when a child component throws.</td></tr><tr><td><code>children</code></td><td><code>React.ReactNode</code></td><td>The component tree to protect.</td></tr></tbody></table>

{% hint style="success" %}
Wrap authentication-critical UI with `HumanityErrorBoundary` as a best practice. See [Error Handling](https://docs.humanity.org/build-with-humanity/build-with-the-sdk-api/humanity-org-react-sdk/broken-reference) for the full pattern.
{% endhint %}

***

## Theming

Customize component appearance with CSS variables:

```css
:root {
  --humanity-primary: #000000;
  --humanity-primary-hover: #222222;
  --humanity-success: #10b981;
  --humanity-error: #ef4444;
  --humanity-border-radius: 8px;
  --humanity-font-family: inherit;
}
```

Set `theme="dark"` or `theme="light"` on `HumanityProvider` to control the built-in theme. `theme="system"` (default) follows the OS preference.
