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

# React SDK

> Add the MoonPay on-ramp widget to a React app using the moonpay-react provider and components.

<Info>
  An example React On-Ramp integration is available in our [GitHub demo
  integrations repo](https://github.com/moonpay/moonpay-demo-integrations).
</Info>

## Install

To integrate MoonPay in your React app, you can use MoonPay's `moonpay-react` package.

```bash theme={null}
npm install @moonpay/moonpay-react
```

Once you've installed this, you're ready to set up your project to integrate the MoonPay widget.

## Add the provider

The first thing to do is add the MoonPay provider to the root of your React application. This will provide context throughout your app to allow you to use the MoonPay widget components.

```typescript setup.ts theme={null}
import { MoonPayProvider } from "@moonpay/moonpay-react";

export default function App() {
  return (
    <MoonPayProvider apiKey="pk_test_123" debug>
      <Home />
    </MoonPayProvider>
  );
}
```

The provider abstracts the complexity of loading the SDK into your app.

Now, use your desired component, passing variant and any parameters related to [Buy](/widget/on-ramp/customization/parameters), [Sell](/widget/off-ramp/customization/parameters), or Swap as props.

The environment is set based on which API key you use. Use the following keys:

* Sandbox environment: `pk_test...`
* Production environment: `pk_live...`

<CodeGroup>
  ```typescript Buy theme={null}
  import { MoonPayBuyWidget } from '@moonpay/moonpay-react';

  export default function Home() {
    return (
      {/*... other components */}
      <MoonPayBuyWidget
        variant="overlay"
        baseCurrencyCode="usd"
        baseCurrencyAmount="100"
        defaultCurrencyCode="eth"
        onLogin={async () => console.log("Customer logged in!")}
        visible
      />
      {/* ... other components*/}
    )
  }

  ```

  ```typescript Sell theme={null}
  import { MoonPaySellWidget } from '@moonpay/moonpay-react';

  export default function Home() {
    return (
      {/* ... other components */}
      <MoonPaySellWidget
        variant="overlay"
        baseCurrencyCode="eth"
        baseCurrencyAmount="0.045"
        visible
      />
      {/* ... other components */}
    )
  }
  ```

  ```typescript Swap theme={null}
  import { MoonPaySwapWidget } from '@moonpay/moonpay-react';

  export default function Home() {
    return (
      {/* ... other components */}
      <MoonPaySwapWidget variant="overlay" visible />
      {/* ... other components */}
    )
  }
  ```

  ```typescript Swap (w/customer setup) theme={null}
  import { MoonPaySwapsCustomerSetupWidget } from '@moonpay/moonpay-react';

  export default function Home() {
    return (
      {/* ... other components */}
      <MoonPaySwapsCustomerSetupWidget
        variant="overlay"
        amount="300"
        amountCurrencyCode="usd"
        onAuthToken={async ({ token }) => {
          // Once the customer has logged in in the widget, we share their
          // swaps-scoped authentication token with your app so you can
          // perform swaps requests on behalf of the customer.
          // The token needs to be passed as an Authorization header in the format
          // "Authorization: Bearer {token}".
          console.log("onAuthToken received with token:", token);
        }}
        onSwapsCustomerSetupComplete={async () => {
          // When this is received, you can close the widget and resume the
          // the swap flow in your UI.
          console.log("onSwapsCustomerSetupComplete received");
        }}
        visible
      />
      {/* ... other components */}
    )
  }
  ```
</CodeGroup>

### For Next.js

For Next.js, it's recommended to dynamically import the MoonPay components as shown below. This ensures efficient loading of the components and prevents server-side rendering (SSR). Otherwise you will see an error message: `ReferenceError: window is not defined`

```typescript theme={null}
import dynamic from "next/dynamic";

const MoonPayProvider = dynamic(
  () => import("@moonpay/moonpay-react").then((mod) => mod.MoonPayProvider),
  { ssr: false },
);

const MoonPayBuyWidget = dynamic(
  () => import("@moonpay/moonpay-react").then((mod) => mod.MoonPayBuyWidget),
  { ssr: false },
);
```

## Variants

### Embedded

The `embedded` variant shows the MoonPay widget will show as part of your page, wherever you place the component. This option lets you fine-tune the placement of the widget and allows you to integrate it into a specific part of your layout. This can minimize context switching for the user.

### Overlay

The `overlay` variant shows the widget as an iframe on top of your website. This option directs the user's attention towards completing their purchase while keeping them on your website.

### New tab

The `newTab` variant opens the widget in a new browser tab. This option lets the user complete their purchase in a full-screen experience. When using this option, tell the user they'll be taken to MoonPay in a new tab. This provides guidance to the user that this is intended and part of the purchase flow.

### New window

The `newWindow` variant opens the widget in a new browser window with a fixed size. This variant is ideal if you want to provide a more controlled experience for the user while they complete their purchase.

## Display

You might want to control whether the SDK is showing based on some application state. This is there the `visible` prop comes into play. Using the `visible` prop makes sure the widget is properly shown and cleaned up as necessary. As a light example, here is how one could add a button to toggle the SDK embedded variant.

<CodeGroup>
  ```typescript highlight={13} Buy theme={null}
  import { MoonPayBuyWidget } from "@moonpay/moonpay-react";

  export default function Home() {
    const [visible, setVisible] = useState(false);

    return (
      <>
        <MoonPayBuyWidget
          variant="overlay"
          baseCurrencyCode="usd"
          baseCurrencyAmount="100"
          defaultCurrencyCode="eth"
          visible={visible}
        />
        <button onClick={() => setVisible(!visible)}>Toggle widget</button>
      </>
    );
  }
  ```

  ```typescript highlight={12} Sell theme={null}
  import { MoonPaySellWidget } from "@moonpay/moonpay-react";

  export default function Home() {
    const [visible, setVisible] = useState(false);

    return (
      <>
        <MoonPaySellWidget
          variant="overlay"
          baseCurrencyCode="eth"
          baseCurrencyAmount="0.045"
          visible={visible}
        />
        <button onClick={() => setVisible(!visible)}>Toggle widget</button>
      </>
    );
  }
  ```
</CodeGroup>

## URL signing

If you're using the `walletAddress` or `walletAddresses` query param, you need to sign your widget URL before you can display the widget. Learn more about [URL signing](/widget/on-ramp/customization/url-signing).

Each of our React components provides an `onUrlSignatureRequested` prop that takes an asynchronous function which is called whenever the URL is updated. It takes an argument of the current URL and the return value should be your generated signature, acquired by some means from your backend by signing the given URL. The widget then takes this returned signature and updates its URL to include it.

```typescript theme={null}
import { MoonPayBuyWidget } from "@moonpay/moonpay-react";

const handleGetSignature = async (url: string): Promise<string> => {
  const signature = await fetch(
    `https://YOUR_API_DOMAIN.com/sign-url?url=${url}`,
  );
  return signature;
};

export default function Home() {
  return (
    <>
      <MoonPayBuyWidget
        variant="overlay"
        baseCurrencyCode="usd"
        baseCurrencyAmount="100"
        defaultCurrencyCode="eth"
        onUrlSignatureRequested={handleGetSignature}
        visible
      />
    </>
  );
}
```
