For the complete documentation index, see llms.txt. This page is also available as Markdown.

JavaScript API

Complete reference for the Alhena Website SDK JavaScript API including all methods, configuration options, and usage examples.

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/):

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.

<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

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


Quick Reference

Methods

Method
Description

Opens the chat widget

Closes the chat widget

Toggles the chat widget open/closed

Sets the expanded view style ('CENTERED' or 'DOCKED')

Sets whether the widget opens in its expanded view

Sends a message as the user

Closes the current conversation and starts a new one

Returns the current ticket/conversation ID

Returns the chat message history

Hides the launcher button

Shows the launcher button

Displays the configured nudge message

Hides any visible nudge, or records that the shopper dismissed it

Triggers the active nudge's click behavior from a custom nudge UI

Updates widget styling dynamically

Overrides the home-screen title at runtime

Overrides the home-screen subtitle at runtime

Switches the widget's language at runtime

Sets a user metadata field

Sets a custom function to format product prices

Decides per product whether a card shows Add to Cart

Tells product cards which products are already in the cart, so they show View Cart

Returns the products in the newest product carousel

Returns the visitor's unique fingerprint

Returns the FAQ widget fingerprint

Removes the widget from the page

Changes the company key dynamically

Subscribes to widget events

Opens the conversational search widget

Closes the conversational search widget

Toggles the conversational search widget

Initializes the conversational search widget

Returns searches and AI questions for your own search box

Opens an embeddable agent from your own button or link

Opens the Product Quiz embeddable agent and asks it a question


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


close()

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


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'


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() / toggle() 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

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 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 (Expanded View).


setDefaultExpanded(expanded, options)

Sets at runtime whether the widget opens expanded or compact, overriding the defaultExpanded option and the dashboard's Open widget expanded by default setting. Useful for varying the default per page.

It applies to the next open() without an expanded argument and to launcher opens. Call it while the widget is closed.

Parameters:

Parameter
Type
Required
Description

expanded

boolean

Yes

true to open expanded, false to open compact. Pass null to go back to the dashboard setting

options

object

No

Configuration options

options.force

boolean

No

Defaults to false. When true, open() and toggle() ignore their own expanded argument


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

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


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.

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


getTicketId()

Returns the unique identifier for the current conversation/ticket.

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


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.


Launcher Control

hideLauncher()

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


showLauncher()

Shows the floating launcher button after it has been hidden.

Use case: Show the launcher only on certain pages:


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, not from the caller. This is useful when you've hidden the default UI (hideDefaultUI: true) and want to control when the nudge shows.


hideNudge(options)

Hides any currently visible nudge message. This also fires the nudge:hidden event, so a custom nudge UI can take itself down.

Parameters:

Parameter
Type
Required
Description

options

object

No

Configuration options

options.dismiss

boolean

No

Set to true when the shopper closed the nudge themselves. Records the dismissal as if they used the built-in close button

showNudge() and hideNudge() take manual control of the nudge. Once you call either one, the timer and scroll triggers configured in your dashboard are ignored for the rest of the page visit — after hideNudge(), only showNudge() will bring the nudge back. hideNudge({ dismiss: true }) is the exception: it records the shopper's dismissal instead of taking manual control.


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.

clickNudge() is intended for use with the nudge:loaded and nudge:triggered events and the hideDefaultUI 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.


Styling

setStyles(styles)

Dynamically updates the widget's visual appearance. See Styles API for all available options.

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

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


Localization

setLocale(locale)

Switches the widget's language without reloading the page. Use it when a shopper changes language or region on your site (for example, from a language switcher on a single-page app). The widget re-translates its built-in text and reloads the translated versions of your dashboard content, such as the welcome message. Messages sent after the switch carry the new locale, so the AI replies in that language and uses the matching market.

You can call it before the widget has finished loading; the new locale is used from the first request.

Parameters:

Parameter
Type
Required
Description

locale

string

Yes

Language code (e.g., 'en', 'es', 'fr'). Same format as the locale configuration option

See Internationalization for how the widget picks its language on page load.


User Data

setUserMetadata(key, value)

Sets a single user metadata field for personalization. Call multiple times to set multiple fields. See Custom Data 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

Keys starting with _ (underscore) are private and not exposed to the AI. Use these for sensitive data like API tokens.


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

See Price Conversion Examples for more usage patterns.


Product Cards

These methods control product cards in the chat widget and read the products the AI has shown. Hooks receive this product data for the selected variant:

Field
Type
Description

variantId

string

The selected variant's ID

masterProductId

string

The product ID

productName

string

The product title

price

number

The selected variant's price

currency

string

Currency code for the price, such as USD

category

string

The product's category

attributes

object

Variant options such as size or color, when your catalog has them

setShouldShowAddToCartHook(hook)

Decides per product whether a card shows Add to Cart, for example to hide it for in-store-only items. It can only hide the button, not add it (see Add to Cart).

Call it after the widget loads, or set document.gleenConfig.shouldShowAddToCart at initialization.

Parameters:

Parameter
Type
Required
Description

hook

function

Yes

Receives the product data above. Return false to hide Add to Cart; anything else keeps it


setIsInCartHook(hook)

Tells product cards which products are already in the cart. When the hook returns true, the card shows View Cart instead of Add to Cart, and clicking it fires the products:view_cart event so your code can open the cart. Off Shopify, the button only shows if you've registered a product:added_to_cart handler.

Call it after the widget loads, or set document.gleenConfig.isInCartHook at initialization.

Parameters:

Parameter
Type
Required
Description

hook

function

Yes

Receives the product data above. Return true if the product is in the cart

The hook must return synchronously; a returned promise counts as not in the cart.


getLatestCarouselProducts(origin)

Returns the products in the newest product carousel the AI has shown in the chat widget or any embeddable agent on the page (not Product FAQs). Outfit and room-set cards are left out.

This is an async method, so await it. Before a chat has loaded it returns undefined, so use await rather than .then().

Parameters:

Parameter
Type
Required
Description

origin

object

No

Limits the search to one chat. Pass the origin from a form or quiz event

Returns: Promise<Array> — one object per product card (empty if none shown), with the product data fields above plus:

Field
Type
Description

cardTitle

string

The card title the AI gave. May be empty

images

array

The product's image URLs

url

string

The product page URL

Use case: Read the products recommended in the chat where a form was submitted:


Analytics & Tracking

getFingerprint()

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

Returns: string — UUID fingerprint.


getFAQFingerprint()

Returns the Product FAQ widget's fingerprint identifier.

Returns: string — UUID fingerprint.


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.


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


Event Subscription

on(eventName, callback)

Subscribes to widget events. See Events 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


Conversational Search Methods

These methods control the Conversational Search widget. The search widget must be set up on your page before these methods will work — see the Conversational Search setup guide 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

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


closeSearch()

Closes the conversational search widget.


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


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).


Search Box Suggestions

Show Alhena's suggestions in your own search box: searches that complete what the shopper is typing, and AI questions about it. Alhena picks the rows. Your code draws the dropdown and decides what happens when the shopper picks one.

The Alhena team turns search suggestions on for your store. Until then, both lists come back empty.

Suggestions come from your catalog and your shoppers' searches. See Where suggestions come from.

For a complete working dropdown, see the Search Box Suggestions example.


getSearchSuggestions(typedText)

Returns suggestions for what the shopper has typed so far. Call it every time your search box changes, and with an empty string when the shopper taps into the empty box.

You only pass the typed text. The SDK adds the page the shopper is on, so the rows fit that page: tapping into the box on a sofa's page suggests things that go with that sofa.

Parameters:

Parameter
Type
Required
Description

typedText

string

No

What the shopper has typed so far. Pass an empty string to get the rows for an empty box.

Returns: a promise that resolves to:

Field
Type
Description

searches

array of { id, text, category }

Searches to show, best first. When the shopper picks one, run your store's search for its text. category names the product category the search belongs to, when known.

aiQuestions

array of { id, text }

Questions to show, best first. To open the Alhena chat with one, call sendMessage(text).

Each row's id stays the same for the same suggestion, so you can use it as a key when you draw the rows.

  • If suggestions take longer than a second, the promise resolves with empty lists, so your dropdown never waits.

  • Answers are remembered while the shopper stays on the page, so deleting a letter doesn't ask again.

  • Until the widget has loaded, the promise resolves with empty lists.


Calling the endpoint directly

If your search dropdown can't call the SDK, for example because another search provider draws it, request the same suggestions over HTTP. No API key is needed, and you pass the page yourself.

GET https://app.alhena.ai/api/get_search_suggestions

For the EU region, use https://eu.alhena.ai.

Query parameter
Required
Description

company_key

Yes

Your company key

q

No

What the shopper has typed so far. Keep a trailing space: it tells Alhena the last word is finished.

page_url

No

The page the shopper is on

page_title

No

That page's title

product_id

No

Your product id, when the shopper is on a product page

phrases are the searches and ai_questions are the AI questions. Other fields in the response are for Alhena's own use. If the request fails, show no rows.

To open the chat with an AI question, call window.gleenWidget.sendMessage(question.text).


Embeddable Agent Methods

These methods control Embeddable Agents. An agent only renders when a placement for it is enabled and matches the current page — see Configuring placements for setup.

launchEmbeddable(agentKey, options)

Opens an embeddable agent as a modal from your own button, link, or other trigger — no data-alhena-embed container or built-in launcher is needed on the page. The agent behaves exactly as if the shopper had tapped its launcher: it recognises the product from the current page and uses the placement's dashboard settings.

Parameters:

Parameter
Type
Required
Description

agentKey

string

Yes

Which agent to open: 'VIRTUAL_TRY_ON', 'SEE_IN_YOUR_ROOM', 'OUTFIT_BUILDER', 'ROOM_DESIGNER', 'PRODUCT_EXPERT' (the Product Quiz), or 'PRODUCT_REVIEWS'. An unknown key is ignored and a warning is logged to the console.

options.instance

string

No

The slug of a specific placement to open. When omitted, the placement is resolved from the current page URL, exactly as the snippet does.

options.message

string

No

For the Product Quiz only: a question to send as the shopper's first message. Must be a non-empty string if provided. Prefer sendQuizMessage for this.

Use case: Put a "Try it on" link in your own product gallery instead of rendering Alhena's button:

Behavior notes:

  • Always opens as a modal. The agent opens in a modal over the page, even if the matching placement is set to render in-page.

  • Safe to call early. If the SDK script hasn't finished loading yet, the call is queued and replayed once it loads. A queued call is dropped if the SDK takes longer than 30 seconds to load, so the agent doesn't pop up unexpectedly long after the shopper clicked.

  • No matching placement, no agent. If no enabled placement for that agent matches the page (or the instance slug you passed), nothing renders and a warning is logged to the console. Your page is unaffected.

  • Each call starts fresh. Calling launchEmbeddable again replaces any agent opened by a previous call.


sendQuizMessage(message, options)

Opens the Product Quiz as a modal and sends message as the shopper's first question. Use it to start the quiz from your own button, link, or form instead of the agent's built-in launcher — no data-alhena-embed container is needed on the page. It is shorthand for launchEmbeddable('PRODUCT_EXPERT', { instance, message }).

Parameters:

Parameter
Type
Required
Description

message

string

Yes

The question to ask. Must be a non-empty string; otherwise the call is ignored and a warning is logged to the console.

options.instance

string

No

The slug of a specific Product Quiz placement to open. When omitted, the placement is resolved from the current page URL, exactly as the snippet does.

Use case: Wire a "Find my fit" button on a collection page, or forward a question a shopper typed into your own input:

Behavior notes:

  • Always opens as a modal. The quiz opens in a modal over the page, even if the matching placement is set to render in-page, and the question is answered inside the quiz panel even when the placement is set to hand off to the full chat widget.

  • Safe to call early. If the SDK script hasn't finished loading yet, the call is queued and replayed once it loads. A queued call is dropped if the SDK takes longer than 30 seconds to load, so the quiz doesn't pop up unexpectedly long after the shopper clicked.

  • No matching placement, no quiz. If no enabled Product Quiz placement matches the page (or the instance slug you passed), nothing renders and a warning is logged to the console. Your page is unaffected.

  • Each call starts fresh. Calling sendQuizMessage again replaces any quiz opened by a previous call and sends the new question.

The Product Quiz is the same agent as the PRODUCT_EXPERT snippet on the Installation page. You can use both on the same site — the snippet for the built-in launcher, and sendQuizMessage for your own.


Configuration Options

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

Basic Configuration

Full Configuration Example

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 the widget in its expanded view. Overrides the dashboard setting; see setDefaultExpanded()

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

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() to change it at runtime

ticket_mode

string

'NORMAL'

'NORMAL' or 'BOT_ONLY'

convertPrice

function

-

Custom function to format product prices

shouldShowAddToCart

function

-

Return false to hide Add to Cart for a product. See setShouldShowAddToCartHook()

getPageProduct

function

-

Tells Alhena which product (and variant) the current page shows, on stores where Alhena can't detect it automatically. See Identifying the Product on the Page

Identifying the Product on the Page

On Shopify, Alhena detects the product a shopper is viewing automatically. On other platforms, define getPageProduct so product-aware features know which product, and which variant, is on the page. Alhena uses it for:

The function takes no arguments and returns an object with the product's ID and, optionally, the selected variant's ID. Use the same IDs as in the product catalog you've connected to Alhena. Return null or an empty object on pages that don't show a single product.

Alhena calls getPageProduct each time it needs the current product, so it can return a different variant after the shopper changes a size or colour. Define it in document.gleenConfig before the SDK script loads so it's available for the first request on the page.


Complete Example


Last updated