> For the complete documentation index, see [llms.txt](https://alhena.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alhena.gitbook.io/docs/developer-reference/website-sdk/javascript-api.md).

# JavaScript API

The Alhena Website SDK provides a JavaScript API for embedding and controlling the chat widget on your website. This page documents all available methods and configuration options.

## Installation

Add the following snippet to your website's HTML, replacing `company` with your company key (found in your dashboard URL after `/dashboard/`):

{% hint style="info" %}
Your company key is the word after "dashboard" in your dashboard URL. For example, if your URL is `https://app.alhena.ai/dashboard/acme/`, your company key is `acme`.
{% endhint %}

```html
<script>
document.gleenConfig = {
    company: 'your-company-key',
    apiBaseUrl: 'https://app.alhena.ai',
};
</script>
<script src="https://app.alhena.ai/sdk/gleenWidget.js"></script>
```

### Regional API URLs

Choose the base URL for your region:

| Region | Base URL                |
| ------ | ----------------------- |
| US     | `https://app.alhena.ai` |
| EU     | `https://eu.alhena.ai`  |

### Complete Installation Example

```html
<script>
document.gleenConfig = {
    company: 'acme',
    apiBaseUrl: 'https://app.alhena.ai'
};
</script>
<script src="https://app.alhena.ai/sdk/gleenWidget.js"></script>
```

You can also find your installation snippet in the Alhena dashboard under **Integrations > Website > Installation**.

***

## Quick Reference

### Methods

| Method                                                                | Description                                                       |
| --------------------------------------------------------------------- | ----------------------------------------------------------------- |
| [`open()`](#open-options)                                             | Opens the chat widget                                             |
| [`close()`](#close)                                                   | Closes the chat widget                                            |
| [`toggle()`](#toggle-options)                                         | Toggles the chat widget open/closed                               |
| [`setExpandedViewMode(mode)`](#setexpandedviewmode-mode)              | Sets the expanded view style (`'CENTERED'` or `'DOCKED'`)         |
| [`sendMessage(message)`](#sendmessage-message-options)                | Sends a message as the user                                       |
| [`closeTicket()`](#closeticket)                                       | Closes the current conversation and starts a new one              |
| [`getTicketId()`](#getticketid)                                       | Returns the current ticket/conversation ID                        |
| [`getMessages()`](#getmessages)                                       | Returns the chat message history                                  |
| [`hideLauncher()`](#hidelauncher)                                     | Hides the launcher button                                         |
| [`showLauncher()`](#showlauncher)                                     | Shows the launcher button                                         |
| [`showNudge()`](#shownudge)                                           | Displays the configured nudge message                             |
| [`hideNudge()`](#hidenudge)                                           | Hides any visible nudge                                           |
| [`clickNudge()`](#clicknudge)                                         | Triggers the active nudge's click behavior from a custom nudge UI |
| [`setStyles(styles)`](#setstyles-styles)                              | Updates widget styling dynamically                                |
| [`setHomeScreenTitle(title)`](#sethomescreentitle-title)              | Overrides the home-screen title at runtime                        |
| [`setHomeScreenSubtitle(subtitle)`](#sethomescreensubtitle-subtitle)  | Overrides the home-screen subtitle at runtime                     |
| [`setUserMetadata(key, value)`](#setusermetadata-key-value)           | Sets a user metadata field                                        |
| [`setConvertPriceHook(hook)`](#setconvertpricehook-hook)              | Sets a custom function to format product prices                   |
| [`getFingerprint()`](#getfingerprint)                                 | Returns the visitor's unique fingerprint                          |
| [`getFAQFingerprint()`](#getfaqfingerprint)                           | Returns the FAQ widget fingerprint                                |
| [`unload()`](#unload)                                                 | Removes the widget from the page                                  |
| [`setCompanyKey(key)`](#setcompanykey-key)                            | Changes the company key dynamically                               |
| [`on(event, callback)`](#on-eventname-callback)                       | Subscribes to widget events                                       |
| [`openSearch(query)`](#opensearch-query)                              | Opens the conversational search widget                            |
| [`closeSearch()`](#closesearch)                                       | Closes the conversational search widget                           |
| [`toggleSearch(query)`](#togglesearch-query)                          | Toggles the conversational search widget                          |
| [`initializeConversationalSearch()`](#initializeconversationalsearch) | Initializes the conversational search widget                      |

***

## Widget Control Methods

### open(options)

Opens the chat widget. If already open, has no effect.

**Parameters:**

| Parameter          | Type    | Required | Description                                                                                                   |
| ------------------ | ------- | -------- | ------------------------------------------------------------------------------------------------------------- |
| `options`          | object  | No       | Configuration options                                                                                         |
| `options.expanded` | boolean | No       | Whether to open in expanded mode                                                                              |
| `options.mode`     | string  | No       | Expanded view style for this open: `'CENTERED'` or `'DOCKED'`. Overrides the configured default for this call |

```javascript
window.gleenWidget.open();

// Open in expanded mode
window.gleenWidget.open({ expanded: true });

// Open expanded as a docked, full-height side panel
window.gleenWidget.open({ expanded: true, mode: 'DOCKED' });
```

***

### close()

Closes the chat widget. If already closed, has no effect.

```javascript
window.gleenWidget.close();
```

***

### toggle(options)

Toggles the chat widget between open and closed states.

**Parameters:**

| Parameter          | Type    | Required | Description                                                        |
| ------------------ | ------- | -------- | ------------------------------------------------------------------ |
| `options`          | object  | No       | Configuration options                                              |
| `options.expanded` | boolean | No       | Whether to open in expanded mode (when toggling open)              |
| `options.mode`     | string  | No       | Expanded view style when toggling open: `'CENTERED'` or `'DOCKED'` |

```javascript
window.gleenWidget.toggle();

// Toggle with expanded mode preference
window.gleenWidget.toggle({ expanded: true });
```

***

### setExpandedViewMode(mode)

Sets how the widget looks when expanded, without opening or closing it. Takes effect the next time the widget is expanded, and persists for the rest of the session (until changed again or overridden by an [`open()`](#open-options) / [`toggle()`](#toggle-options) `mode`).

**Parameters:**

| Parameter | Type   | Required | Description                                                                                                                                                                                        |
| --------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mode`    | string | Yes      | `'CENTERED'` (modal in the middle of the screen) or `'DOCKED'` (full-height panel pinned to the widget's side). Values are case-insensitive; anything other than `DOCKED` falls back to `CENTERED` |

```javascript
// Switch to the docked, full-height side panel
window.gleenWidget.setExpandedViewMode('DOCKED');

// Switch back to the centered modal
window.gleenWidget.setExpandedViewMode('CENTERED');
```

{% hint style="info" %}
On mobile, the expanded view always fills the screen regardless of the mode. The docked panel pins to the same side as your [`widget_position`](/docs/developer-reference/website-sdk/styles-api.md) style — the right by default, or the left when the widget is positioned on the left. You can also set the default view for all visitors from the dashboard — see [Customization](/docs/features/chat-widget/customization.md) (Expanded View).
{% endhint %}

***

### sendMessage(message, options)

Opens the widget and sends a message from the user's perspective. Useful for triggering conversations based on user actions.

**Parameters:**

| Parameter | Type   | Required | Description              |
| --------- | ------ | -------- | ------------------------ |
| `message` | string | Yes      | The message text to send |

```javascript
window.gleenWidget.sendMessage('I need help with my order');
```

**Use case:** Trigger a support conversation when a user clicks a "Help" button:

```javascript
document.getElementById('help-button').addEventListener('click', function() {
    window.gleenWidget.sendMessage('I need assistance');
});
```

***

## Conversation Management

### closeTicket()

Closes the current conversation/ticket and prepares the widget for a new conversation. The user will see the bot's welcome message again.

```javascript
window.gleenWidget.closeTicket();
```

**Use case:** Reset the conversation after a support interaction is complete:

```javascript
window.gleenWidget.on('ticket:agent_handoff', function() {
    setTimeout(function() {
        window.gleenWidget.closeTicket();
        window.gleenWidget.close();
    }, 60000); // Close after 1 minute
});
```

***

### getTicketId()

Returns the unique identifier for the current conversation/ticket.

**Returns:** `string | null` — the ticket ID, or `null` if no active ticket.

```javascript
const ticketId = window.gleenWidget.getTicketId();
console.log('Current ticket:', ticketId);
```

***

### getMessages()

Fetches the message history for the current conversation in markdown format. This is an **async** method — it returns a `Promise` that resolves to an array of message objects, so you must `await` it (or use `.then()`).

**Returns:** `Promise<Array>` — resolves to an array of message objects.

```javascript
const messages = await window.gleenWidget.getMessages();
console.log(messages);
```

***

## Launcher Control

### hideLauncher()

Hides the floating launcher button. The widget can still be opened programmatically.

```javascript
window.gleenWidget.hideLauncher();
```

***

### showLauncher()

Shows the floating launcher button after it has been hidden.

```javascript
window.gleenWidget.showLauncher();
```

**Use case:** Show the launcher only on certain pages:

```javascript
if (window.location.pathname.includes('/support')) {
    window.gleenWidget.showLauncher();
} else {
    window.gleenWidget.hideLauncher();
}
```

***

## Nudge Messages

Nudges are proactive messages that appear near the launcher to encourage users to start a conversation.

### showNudge()

Manually triggers the nudge to appear near the launcher. Takes no arguments — the nudge content comes from your [dashboard nudge settings](/docs/features/chat-widget/nudges.md), not from the caller. This is useful when you've hidden the default UI (`hideDefaultUI: true`) and want to control when the nudge shows.

```javascript
window.gleenWidget.showNudge();
```

***

### hideNudge()

Hides any currently visible nudge message.

```javascript
window.gleenWidget.hideNudge();
```

***

### clickNudge()

Runs the exact same click behavior as the built-in nudge — firing the standard analytics events and opening the conversation. Use this from a **custom nudge UI** so your own elements behave identically to Alhena's default nudge.

```javascript
window.gleenWidget.clickNudge();
```

{% hint style="info" %}
`clickNudge()` is intended for use with the [`nudge:loaded`](/docs/developer-reference/website-sdk/events.md#nudge-loaded) and [`nudge:triggered`](/docs/developer-reference/website-sdk/events.md#nudge-triggered) events and the [`hideDefaultUI`](#configuration-options-reference) config option. Together these let you build a fully custom launcher and nudge UI driven by the standard nudge logic. See the [Custom Launcher & Nudge UI example](/docs/developer-reference/website-sdk/examples/custom-launcher-nudge.md).
{% endhint %}

***

## Styling

### setStyles(styles)

Dynamically updates the widget's visual appearance. See [Styles API](/docs/developer-reference/website-sdk/styles-api.md) for all available options.

```javascript
window.gleenWidget.setStyles({
    widget_position: 'LEFT',
    bottom_spacing: 20,
    right_spacing: 20,
    widget_border_radius: 16
});
```

### setHomeScreenTitle(title)

Overrides the title shown on the widget's home screen at runtime, replacing the value configured in the dashboard. Useful for personalizing the greeting per page or per visitor.

**Parameters:**

| Parameter | Type   | Required | Description                                  |
| --------- | ------ | -------- | -------------------------------------------- |
| `title`   | string | Yes      | The title text to display on the home screen |

```javascript
window.gleenWidget.setHomeScreenTitle('Welcome back, Alex 👋');
```

### setHomeScreenSubtitle(subtitle)

Overrides the subtitle shown beneath the home-screen title at runtime, replacing the value configured in the dashboard.

**Parameters:**

| Parameter  | Type   | Required | Description                                     |
| ---------- | ------ | -------- | ----------------------------------------------- |
| `subtitle` | string | Yes      | The subtitle text to display on the home screen |

```javascript
window.gleenWidget.setHomeScreenSubtitle('How can we help with your order today?');
```

***

## User Data

### setUserMetadata(key, value)

Sets a single user metadata field for personalization. Call multiple times to set multiple fields. See [Custom Data](/docs/developer-reference/website-sdk/custom-data.md) for details.

**Parameters:**

| Parameter | Type   | Required | Description                         |
| --------- | ------ | -------- | ----------------------------------- |
| `key`     | string | Yes      | The metadata key to set             |
| `value`   | any    | Yes      | The value to associate with the key |

```javascript
window.gleenWidget.setUserMetadata('email', 'user@example.com');
window.gleenWidget.setUserMetadata('name', 'John Doe');
window.gleenWidget.setUserMetadata('plan', 'premium');
```

{% hint style="info" %}
Keys starting with `_` (underscore) are private and not exposed to the AI. Use these for sensitive data like API tokens.
{% endhint %}

***

## Price Conversion

### setConvertPriceHook(hook)

Sets a custom function to format product prices before they are displayed in the widget. Useful for currency conversion or localized formatting. Can also be set at initialization via `document.gleenConfig.convertPrice`.

**Parameters:**

| Parameter | Type     | Required | Description                                                              |
| --------- | -------- | -------- | ------------------------------------------------------------------------ |
| `hook`    | function | Yes      | Receives `(price, { variantId })` and returns the formatted price string |

```javascript
window.gleenWidget.setConvertPriceHook(function(price, metadata) {
    const amount = parseFloat(price.replace(/[^0-9.]/g, ''));
    return '€' + (amount * 0.85).toFixed(2);
});
```

See [Price Conversion Examples](/docs/developer-reference/website-sdk/examples/price-conversion.md) for more usage patterns.

***

## Analytics & Tracking

### getFingerprint()

Returns the visitor's unique fingerprint identifier, used for analytics and session tracking.

**Returns:** `string` — UUID fingerprint.

```javascript
const fingerprint = window.gleenWidget.getFingerprint();
```

***

### getFAQFingerprint()

Returns the [Product FAQ](/docs/features/product-faqs.md) widget's fingerprint identifier.

**Returns:** `string` — UUID fingerprint.

```javascript
const faqFingerprint = window.gleenWidget.getFAQFingerprint();
```

***

## Widget Lifecycle

### unload()

Completely removes the widget from the page. Useful for single-page applications when navigating away from pages where the widget should appear.

```javascript
window.gleenWidget.unload();
```

***

### setCompanyKey(key)

Changes the company key dynamically. This reloads the widget with the new company's configuration.

**Parameters:**

| Parameter | Type   | Required | Description         |
| --------- | ------ | -------- | ------------------- |
| `key`     | string | Yes      | The new company key |

```javascript
window.gleenWidget.setCompanyKey('different-company');
```

***

## Event Subscription

### on(eventName, callback)

Subscribes to widget events. See [Events](/docs/developer-reference/website-sdk/events.md) for a complete list of available events.

**Parameters:**

| Parameter   | Type     | Required | Description                      |
| ----------- | -------- | -------- | -------------------------------- |
| `eventName` | string   | Yes      | The event name to listen for     |
| `callback`  | function | Yes      | Function called when event fires |

```javascript
window.gleenWidget.on('widget:opened', function() {
    console.log('Widget was opened');
});

window.gleenWidget.on('ticket:message_submitted', function(data) {
    console.log('User sent:', data.text);
});
```

***

## Conversational Search Methods

These methods control the [Conversational Search](/docs/features/conversational-search.md) widget. The search widget must be set up on your page before these methods will work — see the [Conversational Search setup guide](/docs/features/conversational-search.md) for installation steps.

### openSearch(query)

Opens the conversational search widget. Optionally sends a query immediately.

**Parameters:**

| Parameter | Type   | Required | Description                                                  |
| --------- | ------ | -------- | ------------------------------------------------------------ |
| `query`   | string | No       | A search query to submit automatically when the widget opens |

```javascript
// Open search
window.gleenWidget.openSearch();

// Open search and submit a query
window.gleenWidget.openSearch("running shoes under $100");
```

**Use case:** Connect to your existing search bar so users can switch to AI-powered search:

```javascript
document.querySelector('.ai-search-button').addEventListener('click', function() {
    var searchInput = document.querySelector('#search-input');
    window.gleenWidget.openSearch(searchInput.value);
    searchInput.value = '';
});
```

***

### closeSearch()

Closes the conversational search widget.

```javascript
window.gleenWidget.closeSearch();
```

***

### toggleSearch(query)

Toggles the conversational search widget open or closed. When opening, optionally sends a query.

**Parameters:**

| Parameter | Type   | Required | Description                                    |
| --------- | ------ | -------- | ---------------------------------------------- |
| `query`   | string | No       | A search query to submit when the widget opens |

```javascript
window.gleenWidget.toggleSearch();

// Toggle open with a query
window.gleenWidget.toggleSearch("blue dresses");
```

***

### initializeConversationalSearch()

Manually initializes the conversational search widget. The SDK automatically calls this on page load if the `#alhena-conversational-search` div is present. Use this method if you add the div dynamically after page load (e.g., in a single-page application).

```javascript
// After dynamically adding <div id="alhena-conversational-search"></div>
window.gleenWidget.initializeConversationalSearch();
```

***

## Configuration Options

Configure the widget by setting `document.gleenConfig` before loading the SDK script.

### Basic Configuration

```javascript
document.gleenConfig = {
    company: 'your-company-key',
    apiBaseUrl: 'https://app.alhena.ai'
};
```

### Full Configuration Example

```javascript
document.gleenConfig = {
    company: 'your-company-key',
    apiBaseUrl: 'https://app.alhena.ai',

    // Styling
    styles: {
        widget_position: 'RIGHT',
        bottom_spacing: 20,
        right_spacing: 20,
        widget_border_radius: 16,
        fontFamily: 'Inter, sans-serif'
    },

    // User data
    userMetadata: {
        email: 'user@example.com',
        name: 'John Doe',
        _api_token: 'secret-token' // Private, not sent to AI
    },

    // Localization
    locale: 'es', // Spanish

    // Behavior
    defaultExpanded: false,
    expandedViewMode: 'CENTERED', // or 'DOCKED' for a full-height side panel
    hideLauncher: false,
    hideDefaultUI: false, // Hide built-in launcher + nudge UI to render your own
    ticket_mode: 'NORMAL' // or 'BOT_ONLY'
};
```

### Configuration Options Reference

| Option             | Type     | Default      | Description                                                                                                                                                                                                        |
| ------------------ | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `company`          | string   | -            | Your company key (required)                                                                                                                                                                                        |
| `apiBaseUrl`       | string   | -            | Regional API URL (required)                                                                                                                                                                                        |
| `styles`           | object   | `{}`         | Widget styling options                                                                                                                                                                                             |
| `userMetadata`     | object   | `{}`         | User data for personalization                                                                                                                                                                                      |
| `locale`           | string   | auto         | Language code (e.g., 'en', 'es', 'fr')                                                                                                                                                                             |
| `defaultExpanded`  | boolean  | `false`      | Open widget on page load                                                                                                                                                                                           |
| `hideLauncher`     | boolean  | `false`      | Hide the launcher button                                                                                                                                                                                           |
| `hideDefaultUI`    | boolean  | `false`      | Hide the built-in launcher button **and** nudge UI so you can render your own. Nudge events still fire — see [Custom Launcher & Nudge UI](/docs/developer-reference/website-sdk/examples/custom-launcher-nudge.md) |
| `showExpandButton` | boolean  | `true`       | Show button to expand widget                                                                                                                                                                                       |
| `expandedViewMode` | string   | `'CENTERED'` | Expanded view style: `'CENTERED'` (modal) or `'DOCKED'` (full-height side panel). Overrides the dashboard setting; see [`setExpandedViewMode()`](#setexpandedviewmode-mode) to change it at runtime                |
| `ticket_mode`      | string   | `'NORMAL'`   | `'NORMAL'` or `'BOT_ONLY'`                                                                                                                                                                                         |
| `convertPrice`     | function | -            | Custom function to format product prices                                                                                                                                                                           |

***

## Complete Example

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Alhena Chat Widget Example</title>
</head>
<body>

<h1>Welcome to Our Store</h1>
<button id="help-btn">Get Help</button>
<button id="close-btn">Close Chat</button>

<!-- Alhena SDK Configuration -->
<script>
document.gleenConfig = {
    company: 'your-company-key',
    apiBaseUrl: 'https://app.alhena.ai',
    styles: {
        widget_position: 'RIGHT',
        bottom_spacing: 20
    }
};
</script>
<script src="https://app.alhena.ai/sdk/gleenWidget.js"></script>

<!-- Widget Control -->
<script>
// Button handlers
document.getElementById('help-btn').addEventListener('click', function() {
    window.gleenWidget.open();
});

document.getElementById('close-btn').addEventListener('click', function() {
    window.gleenWidget.close();
});

// Event listeners
window.gleenWidget.on('widget:loaded', function() {
    console.log('Chat widget ready');
});

window.gleenWidget.on('widget:opened', function() {
    console.log('Chat opened');
});

window.gleenWidget.on('ticket:agent_handoff', function() {
    console.log('Transferred to human agent');
});
</script>

</body>
</html>
```

***

## Related Resources

* [Events Reference](/docs/developer-reference/website-sdk/events.md) - Complete list of widget events
* [Styles API](/docs/developer-reference/website-sdk/styles-api.md) - Customizing widget appearance
* [Custom Data](/docs/developer-reference/website-sdk/custom-data.md) - Passing user data to the widget
* [Examples](/docs/developer-reference/website-sdk/examples.md) - Code examples for common use cases
