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

Developer Documentation

Widget Integration Guide

Learn how to embed your custom financial widget into your application using an iframe.

1 Overview

This guide shows you how to embed your custom financial widget into your application using an iframe. Your widget is accessible via a single URL that handles data fetching, theming, and emits real-time events back to your application.

What you can do:

• Embed the widget using a simple iframe

• Configure language, theme, security identifiers, and user behavior

• Listen to widget events (load, resize, user interactions, errors)

• Handle security selections in your application (when enabled)

• Auto-resize the widget based on content

2 Quick Start

Basic iframe integration with auto-resize:

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

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

    try {
      const message = JSON.parse(event.data);
      if (message.event && message.data && message.data.height) {
        document.getElementById("widget").style.height =
          message.data.height + "px";
      }
    } catch (e) {
      // Ignore invalid messages
    }
  });
</script>

3 URL Structure

All 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
languageNoen-US, he-ILUI language (BCP-47 locale), defaults to en-US
tenantYesYour assigned tenant nameTenant namespace provided to you
widgetNameYesstock-report-page / fund-report-pageWhich widget to render

Query Parameters

NameRequiredDefaultDescription
accessTokenYesBearer token used by widgets for data requests
identifierRecommendede.g. AAPL-Nasdaq, 24937The security/fund identifier for data
identifierTypeConditionalticker_exchange / ISINIdentifier type for stock widgets
modeNolight (default) / darkTheme mode
actionTypeNodefault / external / preventControls click behavior on securities
sessionIdYesSession identifier to correlate analytics
userIdYesUser identifier to correlate analytics
i Authentication Required

To start integrating widgets, you'll need an access token. Please follow the instructions in our Authentication Guide to generate your token.

4 Widget-Specific Properties

The following properties are specific to certain widgets:

ParameterRequiredDefaultDescription
userNameNoThe name of the user for personalized interactions
defaultMessageNoDefault prompt message for widget chat interface

5 Selection Behavior (actionType)

The actionType parameter controls how the widget handles clicks on links and securities.

actionTypeBehavior
defaultSelection will redirect to the report page on BridgeWise platform
externalWidget emits on-security-select-<widgetName> event; host app handles navigation
preventClicks are ignored for navigation; no selection event is emitted

6 Events & postMessage

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
}

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 (e.g., 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).

link-click { url: string, text?: string }

Emitted when onLinkClick callback is provided.

Selection Events

security-select { id, ticker?, exchange?, type }

Emitted only when actionType=external.

Event Handler Example

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 errors
    if (message.type === "error") {
      console.error("Widget error:", message.data);
    }
  } catch (e) {
    // Ignore invalid messages
  }
});

7 Theming and Styling

?

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
⚠️

Error Handling

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

Security

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

8 iOS Integration (SwiftUI/UIKit)

For iOS apps, embed the widget using WKWebView with proper postMessage handling:

? 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
  }
}

Key Points for iOS

• Use WKWebView with WKUserContentController for postMessage handling

• Inject JavaScript to bridge iframe postMessage to webkit messageHandler

• Handle height changes to dynamically resize the widget

• Validate message origin for security

• Disable WebView scrolling if you want the widget to control its own height

9 Android Integration (WebView)

For Android apps, use WebView with JavaScript interface to handle postMessage events:

? Kotlin
class WidgetWebView @JvmOverloads constructor(
  context: Context,
  attrs: AttributeSet? = null
) : WebView(context, attrs) {

  init {
    setupWebView()
  }

  @SuppressLint("SetJavaScriptEnabled")
  private fun setupWebView() {
    settings.apply {
      javaScriptEnabled = true
      domStorageEnabled = true
    }

    // Add JavaScript interface for postMessage handling
    addJavascriptInterface(PostMessageHandler(), "AndroidInterface")

    webViewClient = object : WebViewClient() {
      override fun onPageFinished(view: WebView?, url: String?) {
        super.onPageFinished(view, url)
        
        // Inject JavaScript to capture iframe postMessage
        val script = """
          window.addEventListener('message', function(event) {
            if (event.origin !== 'https://embeded.bridgewise.com') return;
            AndroidInterface.handlePostMessage(JSON.stringify(event.data));
          }, false);
        """
        evaluateJavascript(script, null)
      }
    }
  }

  inner class PostMessageHandler {
    @JavascriptInterface
    fun handlePostMessage(messageData: String) {
      // Parse and handle messages
    }
  }
}

Key Points for Android

• Enable JavaScript and DOM storage in WebView settings

• Use @JavascriptInterface to create a bridge for postMessage handling

• Inject JavaScript after page load to capture iframe messages

• Convert pixel heights using display density for proper sizing

• Handle events on the main thread using post()

10 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-size: 14px;">• Embed the widget using a simple iframe