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

# Frontend SDK

> Embed Thred accounting widget in your platform

## Installation

```bash theme={null}
npm install @thredfi/accounting
```

## Quick Start

<Steps>
  <Step title="Add container element">
    Add a div where the widget will mount:

    ```html theme={null}
    <div id="thredfi-widget"></div>
    ```
  </Step>

  <Step title="Import and mount">
    ```typescript theme={null}
    import { mountThredfi } from '@thredfi/accounting';

    mountThredfi({
      thredfiSelector: '#thredfi-widget',
      businessId: 'your-business-uuid',
      getToken: async () => {
        const res = await fetch('/api/thredfi-token');
        const data = await res.json();
        return {
          access_token: data.access_token,
          expires_in: data.expires_in
        };
      },
      environment: 'production',
      lang: 'en'
    });
    ```
  </Step>

  <Step title="Implement token endpoint">
    Create a backend endpoint that returns business-scoped tokens:

    ```python theme={null}
    @app.route('/api/thredfi-token')
    def get_thredfi_token():
        # Get business_id for current user
        business_id = current_user.thred_business_id

        # Get business-scoped token from Thred
        response = requests.post(
            f"https://api.thredfi.com/v1/platform/{business_id}/oauth2/token/",
            headers={"Authorization": f"Bearer {partner_token}"}
        )

        return response.json()
    ```
  </Step>
</Steps>

<Warning>
  **Security: Never hardcode tokens in frontend code**

  The `getToken` function must call your backend to fetch fresh tokens. This keeps your partner credentials secure and allows proper token rotation.
</Warning>

## CDN Usage (No Bundler)

For vanilla JavaScript or server-rendered apps:

```html theme={null}
<!DOCTYPE html>
<html>
<body>
  <div id="thredfi-widget"></div>

  <script src="https://unpkg.com/@thredfi/accounting@latest/dist/index.umd.js"></script>
  <script>
    ThredfiAccounting.mountThredfi({
      thredfiSelector: '#thredfi-widget',
      businessId: 'your-business-uuid',
      getToken: async () => {
        const res = await fetch('/api/thredfi-token');
        return await res.json();
      },
      environment: 'production'
    });
  </script>
</body>
</html>
```

## Configuration Reference

### Required Options

| Option            | Type     | Description                                                    |
| ----------------- | -------- | -------------------------------------------------------------- |
| `thredfiSelector` | string   | CSS selector for container element (e.g., `'#thredfi-widget'`) |
| `getToken`        | function | Async function returning `{access_token, expires_in}`          |
| `businessId`      | string   | Business UUID from Thred                                       |

### Optional Options

| Option        | Type    | Default     | Description                                   |
| ------------- | ------- | ----------- | --------------------------------------------- |
| `environment` | string  | `'sandbox'` | `'sandbox'` or `'production'`                 |
| `lang`        | string  | `'en'`      | Language code (see supported languages)       |
| `basePath`    | string  | `''`        | Base path for routing (e.g., `'/accounting'`) |
| `theme`       | object  | -           | Color overrides for branding                  |
| `hideMenu`    | boolean | `false`     | Hide header navigation                        |

## Theme Customization

Match your platform's visual identity:

```typescript theme={null}
mountThredfi({
  // ... other options
  theme: {
    navigationBackgroundColor: '#f9f9f9',  // Header background
    cardsBackgroundColor: '#ffffff',       // Card/panel background
    textColor: '#111827',                  // Primary text
    textSecondaryColor: '#6b7280',         // Secondary/muted text
    activeColor: '#871f91',                // Active state/links/profit
    borderColor: '#dcdcdc',                // Primary borders
    borderSecondaryColor: '#e5e7eb'        // Light borders
  }
});
```

## Multi-Language Support

| Code    | Language     |
| ------- | ------------ |
| `en`    | English (US) |
| `en-GB` | English (UK) |
| `de`    | German       |
| `es`    | Spanish      |
| `fr`    | French       |
| `it`    | Italian      |
| `nl`    | Dutch        |
| `nb`    | Norwegian    |

Change language dynamically:

```typescript theme={null}
import { setThredfiLanguage } from '@thredfi/accounting';

setThredfiLanguage('de'); // Switch to German
```

## Advanced Configuration

### Custom Routing

If your app uses routing (e.g., `/dashboard/accounting`), set `basePath`:

```typescript theme={null}
mountThredfi({
  // ... other options
  basePath: '/accounting',
  // Widget routes will be: /accounting/invoices, /accounting/reports, etc.
});
```

### Hide Navigation Menu

Hide the widget's header when you want to provide your own navigation:

```typescript theme={null}
mountThredfi({
  // ... other options
  hideMenu: true
});
```

Combine with [menu configuration API](/implementation/menu-configuration) to control which tabs appear.

### Deep Linking

Navigate directly to specific tabs:

```typescript theme={null}
// User lands on /accounting/reports
mountThredfi({
  basePath: '/accounting',
  // ... other options
});

// Widget detects route and shows Reports tab
```

## Environment Configuration

| Environment  | Backend URL                                                | Use For                     |
| ------------ | ---------------------------------------------------------- | --------------------------- |
| `sandbox`    | [https://sandbox.thredfi.com](https://sandbox.thredfi.com) | Development and testing     |
| `production` | [https://api.thredfi.com](https://api.thredfi.com)         | Live production deployments |

## Security Checklist

<AccordionGroup>
  <Accordion title="Backend token generation">
    ✅ **Do:** Fetch tokens from your backend endpoint

    ❌ **Don't:** Generate tokens in frontend code or hardcode credentials
  </Accordion>

  <Accordion title="Token scope">
    ✅ **Do:** Use business-scoped tokens in frontend

    ❌ **Don't:** Expose partner-scoped tokens (grants access to all businesses)
  </Accordion>

  <Accordion title="HTTPS only">
    ✅ **Do:** Serve your app over HTTPS in production

    ❌ **Don't:** Use HTTP (tokens will be exposed)
  </Accordion>

  <Accordion title="Content Security Policy">
    If using CSP, allow:

    * `script-src` for widget JavaScript
    * `connect-src` for API calls to `https://api.thredfi.com` or `https://sandbox.thredfi.com`
    * `frame-src` if widget uses iframes internally
  </Accordion>
</AccordionGroup>

## Resources

* [NPM Package](https://www.npmjs.com/package/@thredfi/accounting)
* [GitHub Repository](https://github.com/thred-fi/frontend)
* [Authentication Guide](/implementation/authentication)
* [Menu Configuration](/implementation/menu-configuration)

***

Widget embedded. Time to [verify your integration](/implementation/verify-integration) works end-to-end.
