> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crxbase.com/llms.txt
> Use this file to discover all available pages before exploring further.

# React

> Share the crxbase client and current-user state across a React extension interface.

Import React integrations from `@crxbase/payments/react`. The root `@crxbase/payments` import remains available for framework-independent code such as a background script.

## Set up the provider

Wrap your popup, options page, or other React interface with `CrxbaseProvider`:

```tsx theme={null}
import { CrxbaseProvider } from "@crxbase/payments/react";

export function App() {
  return (
    <CrxbaseProvider projectId="your_project_id">
      <ExtensionPopup />
    </CrxbaseProvider>
  );
}
```

The provider connects its children to your crxbase project and loads the current user. All components inside it share the same user state. If `projectId` changes, the provider loads the user for the new project.

## Access the client

`useCrxbase` gives you access to the project client. Use it to retrieve tiers or open crxbase pages:

```tsx theme={null}
import { useCrxbase } from "@crxbase/payments/react";

function PricingButton() {
  const crxbase = useCrxbase();

  return (
    <button onClick={() => crxbase.openPricingPage()}>
      View pricing
    </button>
  );
}
```

For a custom pricing interface, call `await useCrxbase().getTiers()` to retrieve your tiers and prices.

## Read user state

`useUser` returns the shared current-user state:

```tsx theme={null}
import { useUser } from "@crxbase/payments/react";

function Account() {
  const { user, loading, isSignedIn, isPaid, error, refresh, logout } = useUser();

  if (error) return <button onClick={refresh}>Try again</button>;
  if (loading) return <span>Loading account…</span>;
  if (!isSignedIn) return <span>Signed out</span>;

  return (
    <div>
      <span>{user.email}</span>
      <span>{isPaid ? "Paid" : "Free"}</span>
      <button onClick={logout}>Log out</button>
    </div>
  );
}
```

| Value        | Meaning                                                                                                                                                                 |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `user`       | The signed-in user, or `null` when signed out.                                                                                                                          |
| `loading`    | `true` while the user is being checked or refreshed.                                                                                                                    |
| `isSignedIn` | `true` when the user is signed in.                                                                                                                                      |
| `isPaid`     | `true` if the user has comped access, a lifetime purchase, or a qualifying recurring subscription (`active`, `trialing`, or `past_due` before its current period ends). |
| `error`      | The error from checking the user, or `null`. An error does not mean the user is signed out.                                                                             |
| `refresh()`  | Checks the latest user and payment status.                                                                                                                              |
| `logout()`   | Signs the user out and updates every component using the provider.                                                                                                      |

Use `useCrxbase` and `useUser` only inside `CrxbaseProvider`.

## Render by user state

`Show` displays its children when `when` matches the user's current state. It supports `signed-in`, `signed-out`, and `paid`, with an optional `fallback`:

```tsx theme={null}
<Show when="paid" fallback={<UpgradePrompt />}>
  <ExportButton />
</Show>
```

When you need the user object, use `render` instead of children. For `signed-in` and `paid`, the function receives the signed-in user and TypeScript knows the user exists:

```tsx theme={null}
import { Show } from "@crxbase/payments/react";

function PaidFeature() {
  return (
    <Show
      when="signed-in"
      render={(user) => (
        <>
          <p>Signed in as {user.email}</p>
          <Show when="paid" fallback={<UpgradePrompt />}>
            <ExportButton />
          </Show>
        </>
      )}
      fallback={<SignInPrompt />}
    />
  );
}
```

Use either children or `render`, not both. `render` is available only for `signed-in` and `paid` because signed-out users do not have a user object. Nesting lets you show different messages to signed-out and signed-in unpaid users. While the user's status is loading or unavailable, `Show` displays neither its content nor `fallback`. Use `useUser` if you want to display a loading or error state.

<Warning>
  `Show` only controls what appears in the interface. It does not protect features or sensitive data. Enforce access in your API or server-side code.
</Warning>
