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
| Name | Required | Format | Description |
|---|
language | No | en-US, he-IL | UI language (BCP-47 locale), defaults to en-US |
tenant | Yes | Your assigned tenant name | Tenant namespace provided to you |
widgetName | Yes | stock-report-page / fund-report-page | Which widget to render |
Query Parameters
| Name | Required | Default | Description |
|---|
accessToken | Yes | — | Bearer token used by widgets for data requests |
identifier | Recommended | e.g. AAPL-Nasdaq, 24937 | The security/fund identifier for data |
identifierType | Conditional | ticker_exchange / ISIN | Identifier type for stock widgets |
mode | No | light (default) / dark | Theme mode |
actionType | No | default / external / prevent | Controls click behavior on securities |
sessionId | Yes | — | Session identifier to correlate analytics |
userId | Yes | — | User 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:
| Parameter | Required | Default | Description |
|---|
userName | No | — | The name of the user for personalized interactions |
defaultMessage | No | — | Default prompt message for widget chat interface |
5 Selection Behavior (actionType)
The actionType parameter controls how the widget handles clicks on links and securities.
| actionType | Behavior |
|---|
default | Selection will redirect to the report page on BridgeWise platform |
external | Widget emits on-security-select-<widgetName> event; host app handles navigation |
prevent | Clicks 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.
Click Event Payload
When a user clicks an actionable control inside a widget (for example a call-to-action button), the widget emits an on-click message via postMessage. The event suffix, the widget value, and the data.id vary depending on the widget and the specific control that was clicked.
For example, the restricted widget served from https://embedded.bridgewise.com/en-US/client/restricted emits a message like the one below. The data.id value (here deposit_now) is defined per client as part of a specific customization — it is not a fixed Bridgewise value:
Click Event Example
{
"event": "on-click-restricted",
"type": "click",
"widget": "restricted",
"data": { "id": "deposit_now" }
}i Handling Click Events
Match on type === "click" and branch on data.id to trigger the corresponding action in your application (e.g., open a deposit flow). Do not assume a fixed widget name or id — both are widget-specific.
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 click events (id is widget-specific)
if (message.type === "click") {
const { id } = message.data;
console.log("Clicked:", id);
}
// 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 DesignWidget automatically adapts to mobile viewports. | ? External NavigationUse actionType=external to keep users in your app. |
⚠️ Error HandlingListen for error events for network/auth issues. | ? Secure StorageUse iOS-size: 14px;">• Embed the widget using a simple iframe |