Bridgewise Article
Home / Integration Guides / Widgets Integration / Bridget Widget Integration Guide
</>

Developer Documentation

Bridget Widget Integration Guide

Learn how to embed Bridget AI chat widgets into your web and mobile applications using iframe integration.

This guide explains how to embed the Bridget widget into your web or mobile application using an <iframe>. The widget URL handles data fetching, theming, and real-time events back to your app.

! Before You Start

Make sure your backend already implements the Bridgewise authentication flow and can provide a valid access token to the frontend. The token must be generated according to the Tenant Authentication guideline.

1 High-Level Integration Journey

A typical Bridget integration follows this end-to-end journey:

1
Backend authentication

Your backend calls the Bridgewise authentication endpoint with your application credentials and receives an access token that Bridget widgets will use for all data calls.

2
Token storage and refresh

The access token is stored securely on the backend and refreshed regularly (every 24 hours), or immediately when authentication errors occur.

3
Frontend requests the token

When a user opens a page that should display Bridget, your frontend calls your backend, retrieves the current access token, and constructs the Bridget widget URL.

4
Widgets are rendered

The frontend embeds Bridget using an iframe: bridget-chat for the full chat experience, or bridget-teaser as a compact teaser.

5
Events and navigation

The widget sends events via postMessage (load, resize, navigation). Your app adjusts iframe height, handles navigation, and opens full chat from teasers.

6
Monitoring and error handling

Your application logs widget events and HTTP errors, reacting to token issues (401/403) by refreshing the token and reloading the widget.

2 Quick Start

Minimal Bridget Chat embed:

HTML
<iframe
  id="widget"
  src="https://embeded.bridgewise.com/en-US/bw/bridget-chat?accessToken=YOUR_TOKEN"
  style="width:100%; border:0; height:400px;"
>
</iframe>

This example uses the default Bridgewise UI (tenant=bw) and the bridget-chat widget.

i Remember to Replace Placeholders

Replace YOUR_TOKEN with your actual access token and bw with your tenant name if using a custom tenant.

3 URL Structure & Available Widgets

3.1 Base URL Format

All Bridget widgets share the same base URL structure:

https://embeded.bridgewise.com/{language}/{tenant}/{widgetName}?accessToken=...&identifier=...&identifierType=...&mode=...&actionType=...&sessionId=...&userId=...&scoringMethod=...

Path Parameters

NameRequiredFormatDescription
languageYesen-US, he-ILUI language (BCP-47 locale)
tenantYesbw or customTenant namespace and theme preset
widgetNameYesbridget-chat / bridget-teaserWhich widget to render

Query Parameters

NameRequiredDescription
accessTokenYesAccess token from your backend
identifierNoSecurity identifier (e.g. AAPL-Nasdaq or ISIN)
modeNolight or dark theme
actionTypeNodefault / external / prevent - controls link behavior
sessionIdYesSession ID for analytics
userIdYesUser ID for analytics

3.2 Available Widgets

?

bridget-chat

Main Bridget app with full chat capabilities and AI-powered responses.

bridget-teaser

Compact teaser with example questions. Redirects to full chat via events.

3.3 Vanilla vs Custom Tenant UI

Default UI — use tenant=bw:

https://embeded.bridgewise.com/en-US/bw/bridget-chat

Custom UI — use your tenant name:

https://embeded.bridgewise.com/en-US/my-tenant/bridget-chat
UI Fallback

You can start using your tenant name before your custom design is ready. Until the custom preset is released, the widget will automatically fall back to the default UI.

4 Bridget-Specific Parameters

The following parameters apply only to the bridget-chat widget and Bridget teaser configuration.

ParameterRequiredDescription
bridget.usernameNoUser's name for personalized interactions and welcome text
bridget.qNoDefault prompt message — skips welcome screen
bridget.event-disclaimerNoSet true to disable default modal, emits open-disclaimer-modal
bridget.event-clipboardNoSet true to disable built-in copy, emits clipboard event
bridget.examplesNoURI-encoded JSON array of example questions for welcome screen (max 4)
teaser.examplesNoURI-encoded JSON array for bridget-teaser widget
bridget.usage-limitNoUser group with limited prompts: novice, intermediate, proficient, advanced, expert
bridget.question-payloadNoURI-encoded JSON array with additional context for prompts

5 Prompt Mapping & URL Construction

Parameters bridget.examples, teaser.examples and bridget.q accept a text/query mapping format. This allows you to display a short label in the UI while sending a more complex prompt to Bridget.

A single mapping is an object:

JSON
[
  { 
    "t": "Give Tesla's price chart", 
    "q": "Show me chart for Tesla with technical indicators" 
  }
]
t

Text shown in UI (buttons, suggestions)

q

Prompt sent to API (optional, defaults to t)

5.1 How to Build the URL

To add examples to the widget URL, you must stringify the JSON array and then URI encode it.

StepActionResult
1Define Array[{ t: "Give Tesla...", q: "Show me..." }]
2JSON.stringify()'[{"t":"Give Tesla...","q":"Show me..."}]'
3encodeURIComponent()%5B%7B%22t%22%3A%22Give%20Tesla...

JavaScript Example:

JavaScript
const baseUrl = "https://embeded.bridgewise.com/en-US/bw/bridget-chat";

// 1. Define the prompts
const examples = [
  { 
    t: "Give Tesla's price chart", 
    q: "Show me chart for Tesla"
  }
];

// 2. Encode
const encodedExamples = encodeURIComponent(JSON.stringify(examples));

// 3. Construct URL
const finalUrl = `${baseUrl}?bridget.examples=${encodedExamples}&accessToken=YOUR_TOKEN`;

console.log(finalUrl);

5.2 Quick Generator

Use this one-liner in your browser's Developer Console to generate the parameter:

CONSOLE
encodeURIComponent(JSON.stringify([
  { t: "Label Name", q: "The actual prompt sent to Bridget" }
]));
Teaser → Chat Experience

Use teaser.examples to define compact teaser buttons. When clicked, bridget-teaser emits bridget-teaser-trigger. Your app should then open bridget-chat and optionally pre-fill bridget.q with the mapped prompt.

6 Events & postMessage

Bridget widgets send JSON-serialized messages to window.parent via postMessage. Each message has this format:

Message Format
{
  "event": "on-<eventName>-<widgetName>",
  "type": "<eventName>",
  "widget": "<widgetName>",
  "data": { ... }  // event-specific payload
}

6.1 Event Types

Status Events

load { height: number }

Widget fully loaded; provides suggested height.

resize { height: number }

Content height changed; use for auto-resize.

success { height: number }

Successful state update (for example, answer rendered).

error { message, status, data?, height }

Error inside the widget or underlying services.

Interaction Events

click { id: string, ... }

Click events (clipboard, disclaimer, etc.).

hover { id: string, ... }

Hover events (where supported).

Navigation Events

navigate { href: string }

Emitted instead of native navigation when actionType=external.

security-select { ticker, exchange, type }

Security selected; use to navigate to your own stock / fund page.

Teaser Widget Events

bridget-teaser-trigger

{ message, companyId, primaryTickerSymbol }

Emitted when a teaser question is clicked in bridget-teaser. Use this to open bridget-chat and pass the prompt.

Call-to-Action Events

click

{ id: "trade", action: "confirm" | "cancel", instrument: { id, name, symbol, type } }

Emitted when a user interacts with the Call-to-action (trade) widget in the chat.

6.2 Basic Event Handler (Web)

JavaScript
window.addEventListener("message", function (event) {
  if (event.origin !== "https://embeded.bridgewise.com") return;

  try {
    const message = JSON.parse(event.data);

    // Auto-resize
    if (message.data && message.data.height) {
      document.getElementById("widget").style.height =
        message.data.height + "px";
    }

    // Handle security selection
    if (message.type === "security-select") {
      const { ticker, exchange } = message.data;
      console.log("Security selected:", ticker, exchange);
    }

    // Handle Bridget teaser trigger
    if (message.type === "bridget-teaser-trigger") {
      const { message: teaserMessage, companyId, primaryTickerSymbol } = message.data;
      console.log("Teaser triggered:", teaserMessage);
    }

    // Handle Call-to-action (Trade)
    if (message.type === "click" && message.data?.id === "trade") {
      const { action, instrument } = message.data;
      console.log(`CTA ${action} for ${instrument.symbol}`);
    }

    // Handle clipboard (if bridget.event-clipboard=true)
    if (message.type === "click" && message.data?.id === "clipboard") {
      console.log("Copy to clipboard:", message.data.text);
    }
  } catch (e) {
    // Ignore invalid messages
  }
});

7 Handling Navigation (actionType)

The actionType query parameter controls how Bridget handles clicks on links and securities.

actionTypeBehavior
defaultAll links behave natively. Security links open the relevant page on the Bridgewise platform.
preventAll link clicks are disabled (no navigation).
externalNo in-widget navigation. Instead, the widget emits navigate and security-select events. Your application decides how to handle navigation.
default

Native browser behavior. All links work as standard HTML links. When a user clicks on a security (stock, fund, etc.), they are redirected to the corresponding page on the Bridgewise platform.

Use case: When you want users to explore the full Bridgewise experience.

prevent

All navigation disabled. Clicking on any link or security does nothing. The widget becomes read-only in terms of navigation.

Use case: Demo environments, restricted access scenarios, or when you want to prevent any external navigation.

external RECOMMENDED

Full control for your application. Instead of navigating, the widget emits events that your application can intercept and handle according to your own routing logic.

When a user clicks a link, you receive a navigate event with the target URL. When they click a security, you receive a security-select event with ticker, exchange, and type information.

Use case: Keeping users within your application, navigating to your own stock/fund pages, or implementing custom routing.

i Best Practice

Use actionType=external to keep users within your application. Handle security-select events to navigate to your own stock or fund pages, providing a seamless integrated experience.

8 Theming, Localization & Security

?

Theming

  • Set mode=dark for dark theme
  • Use width:100% and border:0
  • Rely on resize events for height
?

Localization

  • Set language via path: en-US, he-IL
  • Widget may fall back to defaults
⚠️

Errors

  • Invalid tenant/widget shows error screen
  • Listen for error events
?

Security

  • Validate event.origin
  • Use short-lived tokens
  • Never log tokens in plain text

9 Per-Security Text Customization

When displaying Bridget in context of a specific security, you can use placeholder tokens in customized text lines:

{companyName}{companyTicker}

When you load the widget with an ?identifier=... parameter, these placeholders are automatically replaced with the corresponding company name and ticker.

i Custom Welcome Text

The bridget-teaser already uses placeholders. For bridget-chat welcome screen customization, contact Bridgewise to add personalized text to your tenant preset.

10 Native Mobile Integration

10.1 iOS (SwiftUI / UIKit)

On iOS, embed Bridget using WKWebView, bridge postMessage events into Swift, and adjust view height based on events.

? Swift
struct WidgetView: UIViewRepresentable {
  @Binding var height: CGFloat
  let widgetURL: String

  func makeUIView(context: Context) -> WKWebView {
    let config = WKWebViewConfiguration()
    let controller = WKUserContentController()
    
    // Bridge postMessage -> webkit messageHandler
    let script = """
      window.addEventListener('message', function(e) {
        if (e.origin !== 'https://embeded.bridgewise.com') return;
        webkit.messageHandlers.postMessage.postMessage(e.data);
      }, false);
    """
    controller.addUserScript(WKUserScript(
      source: script,
      injectionTime: .atDocumentStart,
      forMainFrameOnly: false
    ))
    config.userContentController = controller
    
    let webView = WKWebView(frame: .zero, configuration: config)
    webView.load(URLRequest(url: URL(string: widgetURL)!))
    return webView
  }
}

10.2 Android (WebView)

On Android, use WebView with a JavaScript interface to receive messages.

? Kotlin
class WidgetWebView(context: Context) : WebView(context) {
  init {
    settings.javaScriptEnabled = true
    settings.domStorageEnabled = true
    
    addJavascriptInterface(PostMessageHandler(), "AndroidInterface")
    
    webViewClient = object : WebViewClient() {
      override fun onPageFinished(view: WebView?, url: String?) {
        evaluateJavascript("""
          window.addEventListener('message', function(e) {
            if (e.origin !== 'https://embeded.bridgewise.com') return;
            AndroidInterface.handlePostMessage(JSON.stringify(e.data));
          }, false);
        """, null)
      }
    }
  }
  
  inner class PostMessageHandler {
    @JavascriptInterface
    fun handlePostMessage(data: String) {
      // Parse JSON, handle resize/navigation events
    }
  }
}

Key Mobile Integration Points

  • Widget is responsive and adapts to mobile viewports
  • Use actionType=external to handle selections in your app
  • Listen for error events for network/auth issues
  • Store tokens securely (iOS Keychain, Android EncryptedSharedPreferences)
  • Test across device orientations and screen sizes

11 Mobile Integration Notes

?

Responsive Design

Widget automatically adapts to mobile viewports.

?

External Navigation

Use actionType=external to keep users in your app.

⚠️

Error Handling

Listen for error events for network/auth issues.

?

Secure Storage

Use iOS Keychain or Android EncryptedSharedPreferences.

12 Optional: Compression for Long Parameters

If your encoded JSON becomes very long, you can optionally compress it to reduce URL size. This is not mandatory — use only if URL length is a concern.

Compression Steps

1 Stringify the JSON array
2 Apply gzip compression
3 Base64-encode the compressed bytes
4 Prefix with gz_
5 URI-encode the prefixed string
JavaScript Compression Helper
async function compress(str) {
  const blob = new Blob([str]);
  const stream = blob.stream().pipeThrough(
    new CompressionStream("gzip")
  );
  const compressed = await new Response(stream).arrayBuffer();
  return String.fromCharCode.apply(null, new Uint8Array(compressed));
}

async function encode(data) {
  const json = JSON.stringify(data);
  const compressed = await compress(json);
  const base64 = btoa(compressed);
  return encodeURIComponent("gz_" + base64);
}
i When to Use Compression

Only implement compression if you encounter URL length issues. For most use cases, standard URI-encoded JSON is sufficient.

13 Call-to-Action Widget WIP

The widget can be configured to enable call-to-action controls (e.g., Trade buttons) in bot responses. These buttons emit a click event:

Event Payload
{
  "id": "trade",
  "action": "confirm" | "cancel",
  "instrument": {
    "id": "string",
    "name": "string",
    "symbol": "Ticker",
    "type": "string"
  }
}

Use this event to redirect users to a dedicated trading or stock page within your application.