# Getting started

The following document explains how to get started with the Teller Widget, as well as the available customization options.&#x20;

We recommend using the following build configurations/environments for your react apps

1. Vite&#x20;
2. next.js
3. `create-react-app` (although this one is highly unrecommended)

There are additional steps required for the last 2 environments that are outlined at the bottom of this page.

## Installing the widget

### Required packages

```bash
 @tanstack/react-query
 alchemy-sdk
 graphql
 graphql-request
 react
 react-dom
 @teller-protocol/v2-contracts
```

Using either yarn or npm, to install the widget, run the following commands

```bash
yarn add @teller-protocol/teller-widget @tanstack/react-query alchemy-sdk graphql graphql-request react react-dom @teller-protocol/v2-contracts
```

```bash
npm install --save @teller-protocol/teller-widget @tanstack/react-query alchemy-sdk graphql graphql-request react react-dom @teller-protocol/v2-contracts
```

Please note that your app must be running React 18.2.0 or higher, and must have the packages in [#required-packages](#required-packages "mention") and that subgraph studio api key is required for the widget to function properly.

## Using the widget

To use the widget, import it from the package

```jsx
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget subgraphApiKey="xxx" />;
};
```

The widget will work without any additional props or setup required. It will pickup the user's connected wallet and display all available loans for the user's wallet tokens.&#x20;

To generate a subgraph api key from The Graph, used in prop `subgraphApiKey`, follow the steps [here](/teller-widget/generating-subgraph-studio-api-key.md).

## Customizing the widget

The following elements of the widget are customizable

* `buttonLabel`: The label in the button to trigger the widget
* `whitelistedTokens`: Additional tokens to always display
* `showOnlyWhiteListedTokens`: Toggle to show only the tokens defined in `whitelistedTokens`
* `buttonColorPrimary`: #hex background color styling to the main button
* `buttonTextColorPrimary`: #hex text color styling to the main button
* `buttonClassName`: a css class to add to the main button
* `isBareButton`: a boolean that removes all the standard styling and keeps the button to bare minimum for much easier customization
* `referralFee`: Loan fee %, to be sent to a referral address
* `referralAddress`: The address to receive the referral fee
* `welcomeScreenLogo`: Logo (as a URL) displayed on the widget's welcome screen
* `welcomeScreenTitle`: Bold, header text on the widget's welcome screen
* `welcomeScreenParagraph`: Body, paragraph text on the widget's welcome screen

### buttonLabel

You can customize the label that appears in the button once you add it to the your app.&#x20;

By default the label is `Cash Advance`, this can be changed to any string like so

```jsx
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget buttonLabel="Get a loan now!" />;
};
```

### whitelistedTokens

By default, the widget shows available offers for the tokens in the user's wallet.&#x20;

By passing in an object organized by chain id, you can customize this list so the tokens in the list *always* show up in the available loan opportunities. If the token is not found in the user's wallet, the widget will default to a value of 1 for the respective token.&#x20;

```jsx
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

// Object organized by chain id
const whitelistedTokens = {
  // polygon
  [137]: [ 
    "0x61299774020da444af134c82fa83e3810b309991",
    "0x692ac1e363ae34b6b489148152b12e2785a3d8d6",
  ],
  // mainnet
  [1]: ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"],
};

const App = () => {
  return <TellerWidget whitelistedTokens={whitelistedTokens} />;
};
```

### showOnlyWhiteListedTokens

If you want  to *only* show the tokens in the above list, set this prop to true. Please note that for this prop to work, `whitelistedTokens` must be present as well.&#x20;

```jsx
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const whitelistedTokens = {
  [137]: [
    "0x61299774020da444af134c82fa83e3810b309991",
    "0x692ac1e363ae34b6b489148152b12e2785a3d8d6",
  ],
  [1]: ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"],
};

const App = () => {
  return <TellerWidget whitelistedTokens={whitelistedTokens} showOnlyWhiteListedTokens />;
};
```

### buttonColorPrimary

For simple css styling, the primary button's background color can be changed by passing in this prop. The input must be in hex format, including the #, ie #FFFFFF

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget buttonColorPrimary="#HEX" />;
};
```

### buttonTextColorPrimary

Also for simple css styling, the primary button's text color can be changed by passing in this prop. The input must be in hex format, including the #, ie #FFFFFF

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget buttonTextColorPrimary="#HEX" />;
};
```

### buttonClassName

To facilitate styling of the button, and make it easier to match your app's styles, a `buttonClassName` prop is available to add a custom css class to the button.&#x20;

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget buttonClassName="custom-button" />;
};
```

### isBareButton

By setting `isBareButton` to true, all the styling of the button is reset to the browser's default styling to make it easier to override the styling of the button.

```jsx
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget buttonClassName="custom-button" isBareButton />;
};
```

### whitelistedChains

An optional `array` to show desired chains. By default, the widget shows all chains. Available chains:

* 1 (Ethereum),
* 137 (Polygon)
* 42161 (Arbitrum)
* 8453 (Base)

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget whitelistedChains={[1,137]} />;
};
```

### referralFee

Referral fee %, in basis points. For example, 100 = 1%, max 500 = 5%. Note, referral fee on rollover loans is capped at 5% of the original loan repayment.

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget referralFee={100} />;
};
```

### referralAddress

Recipient wallet address to receive referral fee.

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget referralAddress={"0x..."} />;
};
```

### welcomeScreenLogo

Logo (as a URL) displayed on the widget's welcome screen. Image types .png, .jpg, .jpeg, .svg.

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget welcomeScreenLogo={"https://img-url.png"} />;
};
```

### welcomeScreenTitle

Bold, header text on the widget's welcome screen.

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget welcomeScreenTitle={"DeFi's cash advance"} />;
};
```

### welcomeScreenParagraph

Body, paragraph text on the widget's welcome screen.

```javascript
import { Widget as TellerWidget } from "@teller-protocol/teller-widget";

const App = () => {
  return <TellerWidget welcomeScreenParagraph={"Time-based loans, up to thirty days, with no margin-call liquidations."} />;
};
```

## Different environment configurations

### next.js

please add the following to your `next.config.js`

```javascript
webpack: (config, { isServer }) => {
    if (!isServer) {
      config.resolve.fallback = {
        fs: false,
        worker_threads: false,
        module: false,
      };
    }

    return config;
  },
```

### create-react-app

For CRA based environments, multiple steps are required&#x20;

1. Install the following packages

```bash
assert browserify-zlib buffer crypto crypto-browserify encoding fs https-browserify os-browserify path-browserify pino-pretty process react-app-rewired stream-browserify stream-http url vm-browserify
```

2. Modify the start scripts in `package.json` to use `react-app-rewired` instead of `react-scripts`

```json
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"
  },
```

3. Add a `config-overrides.js` file to the top of the project directory with the following

```javascript
const webpack = require("webpack");
module.exports = function override(config, env) {
  config.resolve.fallback = {
    url: require.resolve("url"),
    fs: false,
    assert: require.resolve("assert"),
    crypto: require.resolve("crypto-browserify"),
    http: require.resolve("stream-http"),
    https: require.resolve("https-browserify"),
    os: require.resolve("os-browserify/browser"),
    stream: require.resolve("stream-browserify"),
    path: require.resolve("path-browserify"),
    zlib: require.resolve("browserify-zlib"),
    vm: require.resolve("vm-browserify"),
    worker_threads: false,
    module: false,
    process: require.resolve("process/browser"),
  };
  config.plugins.push(
    new webpack.ProvidePlugin({
      process: "process/browser",
      Buffer: ["buffer", "Buffer"],
    })
  );

  return config;
};
```

*Please note that the following message may appear once the project has been built*

<figure><img src="/files/jplUnbIhWtDwi2Jkl3rV" alt=""><figcaption></figcaption></figure>

*This message can safely be ignored, as this only happens in dev environments. You can either close it by clicking on the x on the top right or by refreshing the page. This message won't appear in production environments*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.teller.org/teller-widget/getting-started.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
