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

# SDK Integration

> Add AI-powered customer support to your website in minutes with a single script

export const api_key_settings = "https://app.eusate.com/settings/integrations?tab=api_keys";

## Overview

The Eusate Messenger SDK is an embeddable chat widget. Drop it into any website and your customers get a fully functional, AI-powered support chat — no backend code required on your end.

It works as a floating button that opens a chat window. Everything inside (messages, calls, agent handover) is handled automatically.

<CardGroup cols={2}>
  <Card title="Script Tag" icon="code">
    Paste one line into your HTML. Best for static sites, plain HTML, or any site where you just want to get started.
  </Card>

  <Card title="NPM Package" icon="cube">
    Install via npm or yarn. Best for React, Next.js, Vue, Angular, Svelte, or any modern framework.
  </Card>
</CardGroup>

***

## Installation

### Script Tag (Quickest)

Paste this into your HTML, just before `</body>`:

```html theme={null}
<script src="https://cdn.eusate.com/messenger/v0/eusate-sdk.min.js"></script>
<script>
  Eusate.init({ apiKey: 'YOUR_API_KEY' })
</script>
```

That's it — the chat widget will appear on your page.

<Info>
  The `v0` path auto-updates with bug fixes and new features within the current major version. To pin to an exact release for maximum stability, use a full version path: `https://cdn.eusate.com/messenger/v0.2.7/eusate-sdk.min.js`
</Info>

### NPM / Yarn

```bash theme={null}
npm install @eusate/messenger-sdk
# or
yarn add @eusate/messenger-sdk
```

***

## Quick Start

### Plain HTML

```html theme={null}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>My Website</title>
  </head>
  <body>
    <h1>Welcome</h1>

    <script src="https://cdn.eusate.com/messenger/v0/eusate-sdk.min.js"></script>
    <script>
      Eusate.init({
        apiKey: 'YOUR_API_KEY',
        onReady: () => console.log('Chat ready'),
        onError: (err) => console.error('Chat error:', err),
      })
    </script>
  </body>
</html>
```

### React

```tsx theme={null}
import { useEffect } from 'react'
import Eusate from '@eusate/messenger-sdk'

function App() {
  useEffect(() => {
    Eusate.init({
      apiKey: process.env.REACT_APP_EUSATE_API_KEY!,
    })

    return () => {
      Eusate.destroy()
    }
  }, [])

  return <div className="App">{/* your content */}</div>
}
```

### Next.js (App Router)

```tsx theme={null}
// app/components/ChatWidget.tsx
'use client'

import { useEffect } from 'react'
import Eusate from '@eusate/messenger-sdk'

export default function ChatWidget() {
  useEffect(() => {
    Eusate.init({
      apiKey: process.env.NEXT_PUBLIC_EUSATE_API_KEY!,
      onReady: () => console.log('Chat ready'),
      onError: (error) => console.error('Chat error:', error),
    })

    return () => {
      Eusate.destroy()
    }
  }, [])

  return null
}
```

```tsx theme={null}
// app/layout.tsx
import ChatWidget from './components/ChatWidget'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        <ChatWidget />
      </body>
    </html>
  )
}
```

<Info>
  The `'use client'` directive is required — the SDK uses browser APIs (`window`, `document`) that are not available during server-side rendering.
</Info>

### Vue 3

```vue theme={null}
<!-- App.vue -->
<script setup>
import { onMounted, onUnmounted } from 'vue'
import Eusate from '@eusate/messenger-sdk'

onMounted(() => {
  Eusate.init({ apiKey: import.meta.env.VITE_EUSATE_API_KEY })
})

onUnmounted(() => {
  Eusate.destroy()
})
</script>
```

***

## Configuration

### `Eusate.init(config)`

<ParamField path="apiKey" type="string" required>
  Your API key. Get it from <a href={api_key_settings} target="_blank">API Key Settings</a>.
</ParamField>

<ParamField path="environment" type="string">
  Target environment. `"production"` (default) or `"development"`. Use `"development"` while testing.
</ParamField>

<ParamField path="onReady" type="() => void">
  Callback fired when the widget is loaded and ready to use.
</ParamField>

<ParamField path="onError" type="(error: Error) => void">
  Callback fired if initialization fails (invalid API key, network issues, etc.).
</ParamField>

```javascript theme={null}
Eusate.init({
  apiKey: 'your-api-key',
  environment: 'production',
  onReady: () => {
    console.log('Eusate is ready')
  },
  onError: (error) => {
    console.error('Eusate failed to load:', error)
  },
})
```

### Environment Variables

<CodeGroup>
  ```env Next.js theme={null}
  # .env.local
  NEXT_PUBLIC_EUSATE_API_KEY=your-api-key-here
  ```

  ```env React (CRA) theme={null}
  # .env
  REACT_APP_EUSATE_API_KEY=your-api-key-here
  ```

  ```env Vue / Vite theme={null}
  # .env
  VITE_EUSATE_API_KEY=your-api-key-here
  ```
</CodeGroup>

***

## Methods

### `Eusate.open()`

Programmatically open the chat window.

```javascript theme={null}
Eusate.open()

// Example: open on button click
document.getElementById('help-btn').onclick = () => Eusate.open()
```

***

### `Eusate.close()`

Programmatically close the chat window.

```javascript theme={null}
Eusate.close()
```

***

### `Eusate.destroy()`

Remove the widget from the page entirely. Useful for cleanup in single-page apps when navigating away.

```javascript theme={null}
Eusate.destroy()
```

<Warning>
  After calling `destroy()`, you must call `init()` again to re-add the widget.
</Warning>

***

### `Eusate.isInitialized()`

Returns `true` if the widget has loaded and is ready.

```javascript theme={null}
if (Eusate.isInitialized()) {
  Eusate.open()
}
```

***

### `Eusate.isOpen()`

Returns `true` if the chat window is currently visible.

```javascript theme={null}
if (!Eusate.isOpen()) {
  showPrompt('Need help? Chat with us!')
}
```

***

### `Eusate.version`

The current SDK version string.

```javascript theme={null}
console.log(Eusate.version) // "0.2.7"
```

***

## Advanced Usage

### Custom Trigger Button

Use your own button to open the chat instead of the default floating button:

```html theme={null}
<button id="chat-trigger">💬 Talk to support</button>

<script src="https://cdn.eusate.com/messenger/v0/eusate-sdk.min.js"></script>
<script>
  Eusate.init({ apiKey: 'your-key' })
  document.getElementById('chat-trigger').onclick = () => Eusate.open()
</script>
```

### Conditional Loading

Only load the widget for certain users:

```javascript theme={null}
if (user.isAuthenticated) {
  Eusate.init({ apiKey: process.env.NEXT_PUBLIC_EUSATE_API_KEY })
}
```

### Route Change Handling (SPAs)

Close the chat when navigating between pages:

```javascript theme={null}
// Next.js App Router
useEffect(() => {
  return () => Eusate.close()
}, [pathname])
```

***

## Security

<Warning>
  Never hardcode your API key in client-side code or commit it to version control. Always use environment variables.
</Warning>

### Content Security Policy (CSP)

If your site enforces CSP headers, add these directives to allow the widget:

```
Content-Security-Policy:
  frame-src https://chat.eusate.com;
  script-src https://cdn.eusate.com;
  connect-src https://api.eusate.com;
```

***

## Troubleshooting

### Widget not appearing

```javascript theme={null}
// Add callbacks to see exactly what's happening
Eusate.init({
  apiKey: 'your-key',
  onReady: () => console.log('✅ SDK ready'),
  onError: (error) => console.error('❌ SDK error:', error),
})

console.log('Initialized?', Eusate.isInitialized())
```

Also check:

* API key is correct and active in your dashboard
* No browser extensions (ad blockers) are intercepting the script
* JavaScript is enabled

### Next.js: "window is not defined"

You're importing the SDK in a server component. Add `'use client'` at the top of the file, or use dynamic import:

```tsx theme={null}
import dynamic from 'next/dynamic'

const ChatWidget = dynamic(() => import('./components/ChatWidget'), {
  ssr: false,
})
```

### Widget appears more than once

You're calling `init()` multiple times. Use an empty dependency array in React:

```tsx theme={null}
// ✅ Correct — runs once on mount
useEffect(() => {
  Eusate.init({ apiKey: 'key' })
  return () => Eusate.destroy()
}, [])

// ❌ Wrong — re-runs when someValue changes
useEffect(() => {
  Eusate.init({ apiKey: 'key' })
}, [someValue])
```

***

## More Frameworks

<CardGroup cols={2}>
  <Card title="Next.js Pages Router" icon="file-code">
    ```tsx theme={null}
    // pages/_app.tsx
    import { useEffect } from 'react'
    import Eusate from '@eusate/messenger-sdk'

    export default function App({ Component, pageProps }) {
      useEffect(() => {
        Eusate.init({ apiKey: process.env.NEXT_PUBLIC_EUSATE_API_KEY! })
        return () => Eusate.destroy()
      }, [])

      return <Component {...pageProps} />
    }
    ```
  </Card>

  <Card title="Angular" icon="a">
    ```typescript theme={null}
    // app.component.ts
    import { Component, OnInit, OnDestroy } from '@angular/core'
    import Eusate from '@eusate/messenger-sdk'

    @Component({ selector: 'app-root', templateUrl: './app.component.html' })
    export class AppComponent implements OnInit, OnDestroy {
      ngOnInit() {
        Eusate.init({ apiKey: environment.eusateApiKey })
      }
      ngOnDestroy() {
        Eusate.destroy()
      }
    }
    ```
  </Card>

  <Card title="Svelte" icon="bolt">
    ```svelte theme={null}
    <script>
      import { onMount, onDestroy } from 'svelte'
      import Eusate from '@eusate/messenger-sdk'

      onMount(() => {
        Eusate.init({ apiKey: import.meta.env.VITE_EUSATE_API_KEY })
      })
      onDestroy(() => Eusate.destroy())
    </script>
    ```
  </Card>
</CardGroup>

***

## Next Steps

* [Socket.IO Events](/modules/helpdesk/socketio) — build a fully custom chat UI from scratch
* [REST API Reference](/modules/helpdesk/api-reference) — fetch conversations and messages via HTTP
