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

# React

> Learn how to use the Authsignal React SDK.

The Authsignal React SDK builds on top of the [Web SDK](/sdks/client/web/setup) by providing UI components which can be added to your React app.

<Note>The Authsignal React SDK currently only supports re-authentication flows.</Note>

<Frame caption="An example of the UI components in a checkout flow.">
  <video controls className="w-full aspect-video" src="https://mintcdn.com/authsignal-23/o0kRW78VfDNgNDjk/images/docs/react-sdk/react-sdk-drawer.mp4?fit=max&auto=format&n=o0kRW78VfDNgNDjk&q=85&s=d40edf650ed5a46f536f7bd5c4746bde" data-path="images/docs/react-sdk/react-sdk-drawer.mp4" />
</Frame>

<Card title="GitHub repository" icon="github" href="https://github.com/authsignal/authsignal-react" horizontal />

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @authsignal/react
  ```

  ```bash yarn theme={null}
  yarn add @authsignal/react
  ```

  ```bash pnpm theme={null}
  pnpm add @authsignal/react
  ```

  ```bash bun theme={null}
  bun add @authsignal/react
  ```
</CodeGroup>

## AuthsignalProvider component

The `AuthsignalProvider` component allows you to use the [useAuthsignal hook](/sdks/client/react#useauthsignal-hook). Render the `AuthsignalProvider` component
at the root of your application so that it is available everywhere you need it.

```tsx theme={null}
import { AuthsignalProvider } from "@authsignal/react";

import { Checkout } from "./Checkout";

export function App() {
  return (
    <AuthsignalProvider tenantId="{{TENANT_ID}}" baseUrl="{{BASE_URL}}">
      <Checkout />
    </AuthsignalProvider>
  );
}
```

The `AuthsignalProvider` component accepts the following props:

<ResponseField name="tenantId" type="string" required>
  Your tenant ID. It can be found in the [API
  keys](https://portal.authsignal.com/organisations/tenants/api) section.
</ResponseField>

<ResponseField name="baseUrl" type="string">
  Your tenant's API URL. It can be found in the [API
  keys](https://portal.authsignal.com/organisations/tenants/api) section.
</ResponseField>

<ResponseField name="appearance" type="object">
  Customize the design of the UI components.

  <Expandable>
    <ResponseField name="variables" type="object">
      Set variables to customize the appearance of the UI components. Each variable accepts a valid
      CSS value.

      <Expandable>
        <ResponseField name="colorPrimary" type="string">
          Your brand's primary color. Used for buttons.
        </ResponseField>

        <ResponseField name="colorPrimaryForeground" type="string">
          The foreground color for the primary color. Used for text on buttons.
        </ResponseField>

        <ResponseField name="colorBackground" type="string">
          The color used for the background.
        </ResponseField>

        <ResponseField name="colorForeground" type="string">
          The foreground color for the background. Used for text.
        </ResponseField>

        <ResponseField name="colorDanger" type="string">
          The color used to indicate errors.
        </ResponseField>

        <ResponseField name="colorRing" type="string">
          The color used for the focus ring.
        </ResponseField>

        <ResponseField name="colorInputBorder" type="string">
          The color used for input borders.
        </ResponseField>

        <ResponseField name="spacingUnit" type="string">
          The base unit of spacing.
        </ResponseField>

        <ResponseField name="borderRadius" type="string">
          The border radius used for buttons and inputs.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

## useAuthsignal hook

The `useAuthsignal` hook returns two functions, `startChallenge` and `startChallengeAsync`, that you can use to
trigger the authentication flow.

Both functions require a `token` to be passed as an argument. The `token` should be
returned by your server after [tracking an action](/api-reference/server-api/track-action).

### `startChallenge`

The `startChallenge` function triggers the authentication flow.

```tsx theme={null}
import { useAuthsignal } from "@authsignal/react";

export function Checkout() {
  const { startChallenge } = useAuthsignal();

  const handlePayment = async () => {
    const response = await fetch("/api/payment", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
    });

    const data = await response.json();

    if (data.token) {
      startChallenge({
        token: data.token,
        onChallengeSuccess: ({ token }) => {
          // Challenge was successful
          // Send the token to your server to validate the challenge
        },
        onCancel: () => {
          // User cancelled the challenge
        },
        onTokenExpired: () => {
          // Token expired
        },
      });
    }
  };

  return (
    <div>
      <button type="button" onClick={handlePayment}>
        Pay
      </button>
    </div>
  );
}
```

As well as a `token`, the `startChallenge` function accepts the following callbacks:

<ResponseField name="onChallengeSuccess" type="function">
  A callback function that is called when the challenge is successful. It receives an object with a
  `token` property. This `token` should be sent to your server to [validate the
  challenge](/sdks/server/challenges#validate-challenge).
</ResponseField>

<ResponseField name="onCancel" type="function">
  A callback function that is called when the user cancels the challenge.
</ResponseField>

<ResponseField name="onTokenExpired" type="function">
  A callback function that is called when the token expires.
</ResponseField>

### `startChallengeAsync`

Alternatively, you can use the `startChallengeAsync` function, which returns a `Promise` that resolves with a `token` when the challenge is successful.
It will throw a `ChallengeError` if the user cancels the challenge or the token expires.

```tsx theme={null}
import { useAuthsignal, ChallengeError } from "@authsignal/react";

export function Checkout() {
  const { startChallengeAsync } = useAuthsignal();

  const handlePayment = async () => {
    const response = await fetch("/api/payment", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
    });

    const data = await response.json();

    if (data.token) {
      try {
        const { token } = await startChallengeAsync({
          token: data.token,
        });

        // Challenge was successful
        // Send the token to your server to validate the challenge
      } catch (e) {
        if (e instanceof ChallengeError) {
          if (e.code === "USER_CANCELED") {
            // User cancelled the challenge
          } else if (e.code === "TOKEN_EXPIRED") {
            // Token expired
          }
        }
      }
    }
  };

  return (
    <div>
      <button type="button" onClick={handlePayment}>
        Pay
      </button>
    </div>
  );
}
```

## Customizing the appearance

You can customize the appearance of the UI components by passing an `appearance` prop to the [AuthsignalProvider component](/sdks/client/react#authsignalprovider-component).

```tsx theme={null}
import { AuthsignalProvider } from "@authsignal/react";

import { Checkout } from "./Checkout";

export function App() {
  return (
    <AuthsignalProvider
      tenantId="{{TENANT_ID}}"
      baseUrl="{{BASE_URL}}"
      appearance={{
        variables: {
          borderRadius: "0.5rem",
          colorBackground: "#0A2540",
          colorPrimary: "#EFC078",
          colorPrimaryForeground: "#1A1B25",
          colorForeground: "white",
        },
      }}
    >
      <Checkout />
    </AuthsignalProvider>
  );
}
```

<Frame>
  <img src="https://mintcdn.com/authsignal-23/o0kRW78VfDNgNDjk/images/docs/react-sdk/react-sdk-appearance.png?fit=max&auto=format&n=o0kRW78VfDNgNDjk&q=85&s=ba56a8a6a2d0df28d97fbfe29de8027a" alt="" width="429" height="553" data-path="images/docs/react-sdk/react-sdk-appearance.png" />
</Frame>
