MojarMojar
DevelopersEmbed SDK

Loader script

How the widget-mojar-loader.js script boots, what data attributes it reads, and the JS API it exposes.

The loader script (widget-mojar-loader.js) is a self-contained IIFE that initialises the Mojar chat widget. This page covers its internal boot sequence, every data-* attribute it reads, the JavaScript API it exposes on window, and the postMessage events it handles.

For the quickest path to adding the widget, start at install the SDK. For the full attribute reference (visual/UX options) see embed widget — configuration.

Boot sequence

When the browser parses the <script> tag, the loader runs this sequence:

Guard against double-initialisation. If window.mojarAiWidgetLoaded is already true, the script exits immediately. This protects against the tag being included more than once.

Read configuration from data-* attributes on the <script> element via document.currentScript.dataset. If data-agentid or data-domainuuid is missing, the script exits silently.

Expose the JS API (window.MojarAIWidget / window.MojarAIWidgetV2) immediately so calling code can call open() before the network requests complete.

Set up tab-visibility handling. A visibilitychange listener silently refreshes the session token when the user returns to the tab and the token is within 2 minutes of its 25-minute expiry.

Validate the agent and domain by posting to /api/embed/initiate-session on the Mojar host. On success, a short-lived session token is returned.

Inject animation styles (<style id="mojar-widget-animations">) and issue an iframe <link rel="preload"> for the embed chat page so the first open is faster.

Create the toggle button (unless data-hide-button="true"). If data-modal-open-by-default="true", the iframe is loaded immediately instead of waiting for the first click.

The iframe itself is created lazily — only when the user clicks the toggle button for the first time (or when data-modal-open-by-default="true").

Data attributes

The following attributes are read from the <script> tag. Required attributes must be present or the widget will not initialise.

Required

AttributeDescription
data-agentidUUID of the Mojar agent to embed.
data-domainuuidUUID of the registered embed domain for the calling origin.

Button

AttributeDefaultDescription
data-button-positionbottom-rightWhere the toggle button appears. One of bottom-right, bottom-left, top-right, top-left.
data-button-themeprimaryVisual preset: primary (dark navy), dark, or light. Overridden by custom color attributes.
data-button-textAsk AILabel rendered below the icon.
data-hide-buttonfalseSet to "true" to suppress the toggle button entirely. Use the JS API to open/close programmatically.

Colors

AttributeDefaultDescription
data-background#CCFF33Primary background color passed to the iframe.
data-accent#FF2C63Accent color passed to the iframe (used for the button icon).
data-text-color#11113APrimary text color.
data-accent-text-colorText color on accented elements.
data-card-color#FFFFFFCard/surface background color.
data-info-text-colorMuted/informational text color.
data-close-button-colorClose button icon color.
data-close-button-hover-colorClose button icon color on hover.

Other options

AttributeDefaultDescription
data-modal-open-by-defaultfalseOpen the widget immediately on page load.
data-user-nameOptional display name passed into the chat session.
data-project-logoURL of a logo to display inside the chat iframe.
data-contact-emailContact email surfaced inside the chat for support fallback.
data-mobile-fullscreenfalseForce fullscreen layout on all viewports (intended for testing only — production automatically applies fullscreen on viewports ≤ 768 px).

Iframe layout

On desktop (viewport > 768 px), the iframe renders as a centered modal: width: 90%, max-width: 900px, height: 80vh, with 32 px border-radius.

On mobile (viewport ≤ 768 px), the iframe fills the viewport: position: fixed; inset: 0; width: 100vw; height: 100dvh. Only the messages list scrolls; the input is fixed at the bottom.

The loader listens to resize and orientationchange events and re-applies these styles dynamically.

JavaScript API

After successful initialisation, the loader exposes the widget API on two global names (both point to the same object):

  • window.MojarAIWidget
  • window.MojarAIWidgetV2
window.MojarAIWidget.open()        // Show the widget (loads iframe on first call)
window.MojarAIWidget.close()       // Hide the widget with a slide-down animation
window.MojarAIWidget.toggle()      // Open if closed, close if open
window.MojarAIWidget.destroy()     // Fully tear down the widget and release all listeners
window.MojarAIWidget.reinitialize()// Re-validate credentials and recreate the toggle button

open(), close(), and toggle() are no-ops while an animation is in progress (debounced at ~250–300 ms) to prevent visual jank from rapid successive calls.

Example — open the widget from your own button:

<button onclick="window.MojarAIWidget.open()">Talk to us</button>

<script
  src="https://app.mojar.ai/widget-mojar-loader.js"
  data-agentid="YOUR_AGENT_UUID"
  data-domainuuid="YOUR_DOMAIN_UUID"
  data-hide-button="true"
></script>

postMessage events

The loader listens for message events from the iframe. Events from origins other than the Mojar host are ignored.

typeactionWhat the loader does
MOJAR_WIDGET_COMMANDclose_widgetCalls MojarAIWidget.close().
MOJAR_WIDGET_COMMANDreinitializeSessionCalls initializeValidationAndCreateButton() — re-validates the agent/domain and recreates the button.
MOJAR_WIDGET_COMMANDREQUEST_NEW_SESSION_TOKENTriggers an immediate silent token refresh and posts the new token back to the iframe as { type: "NEW_SESSION_TOKEN", token }.

Session token lifecycle

The session token has a 25-minute lifetime (TOKEN_EXPIRY_MS = 25 * 60 * 1000). The loader schedules a setTimeout to silently call POST /api/embed/generate-token (with the agent and domain UUIDs) before expiry, then posts the refreshed token into the iframe via postMessage. On tab re-focus, if more than 23 minutes have passed since the last refresh, a refresh is triggered immediately.

Error display

If the initial session call fails, the loader renders a small error banner near the toggle button (positioned to match data-button-position) that auto-dismisses after 8 seconds. The toggle button enters an error state (red background, disabled pointer events) and reverts to normal if the widget is successfully reinitialized.

On this page