# Implementation

## Step 1 - Authorize your project

#### The Widget is a Browser-only SDK

#### For testing

Use a tool such as ngrok (<https://ngrok.com/docs/http/>) to get a unique URL for your web app running locally on your device and add it to your allowlist. \
\
See: [allowlisting via the admin dashboard](https://docs.chainvine.xyz/developers/sdk/classes-and-functions/authentication/allow-listing-a-domain).

#### For production

Add your production domain by [allowlisting it via the admin dashboard](https://docs.chainvine.xyz/developers/sdk/classes-and-functions/authentication/allow-listing-a-domain)

## Step 2 - Add the package

Install the package in your project

{% code overflow="wrap" %}

```bash
npm install @chainvine/widget
```

{% endcode %}

or

{% code overflow="wrap" %}

```bash
yarn add @chainvine/widget
```

{% endcode %}

## Step 3 - Add the Widget Component

Here is an example using a React component called "App".

### React

```typescript
import React from "react";
import "./App.css";
import { ChainvineWidget } from "@chainvine/widget";

const App = () => {
  const [isOpen, setIsOpen] = React.useState<boolean>(false);

  const openWidget = () => {
    setIsOpen(true);
  }
  const closeWidget = () => {
    setIsOpen(false);
  }

  return (
   <div>
     <button
        type={'submit'}
        onClick={() => {
          openWidget()
        }}>
        Open me
      </button>
      <ChainvineWidget
        isOpen={isOpen}
        userIdentifier={walletAddress}
        identifierType={'wallet'}
        campaignId={campaignId}
        onToggle={() => closeWidget()} 
      />
    </div>
  );
}
```

### NextJS/SSR

For server-side rendered projects, please ensure to wrap the widget component inside a client-side rendered component. For NextJS, a simple way to do this is by using the `'use-client'` tag at the top of your file:

```typescript
'use-client' //<--- IMPORTANT
import React from "react";
import "./App.css";
import { ChainvineWidget } from "@chainvine/widget";

export const MyClientSideWidgetComponent = () => {
  const [isOpen, setIsOpen] = React.useState<boolean>(false);

  const openWidget = () => {
    setIsOpen(true);
  }
  const closeWidget = () => {
    setIsOpen(false);
  }

  return (
    <div>
      <button
        type={'submit'}
        onClick={() => {
          openWidget()
        }}>
        Open me
      </button>
      <ChainvineWidget
        isOpen={isOpen}
        userIdentifier={walletAddress}
        identifierType={'wallet'}
        campaignId={campaignId}
        onToggle={() => closeWidget()} 
      />
    </div>
  );
}
```

Note: if your flow does not include a wallet connect step, we also support an identifier type of 'email' and 'externalId' where the externalId can be any unique user identifier within your system.

### Guidances

* When in desktop screen sizes: you must pass in the component around which the Widget will be positioned on the screen as a child component.&#x20;
  * In this example, we use a button, however, you can use any component that suits your needs, as long as it is able to update *isOpen* state hook in the example.
  * This example uses a useState hook, however you can very well use other state hooks such as Redux, or other  context providers.

## Step 4 - Testing&#x20;

### How to test

The ChainVine widget uses the ChainVine SDK under the hood. The *clientConfig* prop of the Widget is an extension of the ChainVine SDK's ***ClientConfig*** constructor options.

Refer to the [ChainVine SDK documentation](https://docs.chainvine.xyz/developers/sdk/configuring-the-client) for how to setup testMode and ClientConfig options.&#x20;

## That's it!

If you have any questions, or run into any issues, please do not hesitate to reach out on [Telegram](https://t.me/chainvinehq)!

##
