Mobile SDKs
Native SDKs for embedding the widget in mobile apps, published as open source (MIT) on GitHub under github.com/Odditt-Betflow:
| Platform | Repo | Install | Minimum |
|---|---|---|---|
| Flutter | odditt-flutter-sdk | Git dependency (pub.dev planned) | - |
| React Native | odditt-react-native-sdk | npm install @odditt/react-native-sdk react-native-webview | - |
| iOS | odditt-ios-sdk | Swift Package Manager or CocoaPods | iOS 13+ |
| Android | odditt-android-sdk | JitPack (com.github.Odditt-Betflow:odditt-android-sdk) | SDK 21+ |
Each SDK is a thin, typed wrapper around a platform WebView rendering your widget deployment - no custom native modules, no separate API integration. If your app is hybrid (Capacitor / Cordova / Ionic), you don't need an SDK at all: the standard iframe embed works unchanged inside your app's WebView.
Shared Concepts
All four SDKs expose the same surface, so integration knowledge transfers across platforms:
OddittWidget- the embed component (SwiftUI/Compose;OddittWidgetViewfor UIKit/Android Views).baseUrl(required) - your widget deployment URL, provided by the Odditt team.OddittWidgetConfig- typed configuration mirroring the iframe parameters in camelCase:country,colorMode(dark/light),layoutMode(carousel/feed),oddsFormat,widgetMode(operator/affiliate/clean),productMode(sportsbook/dfs/prediction_market),sportIds, plus anextraParamsmap for any other documented iframe parameter (preset,lang,leagueKey,includeAltLines, filter params, ...).- Typed event callbacks - the same events as the web widget's postMessage stream, delivered natively: a universal
onSignalplus granularonBetClicked,onReady,onEmpty,onError, andonExternalUrl. Signal types:WIDGET_READY,WIDGET_EMPTY,WIDGET_ERROR,BET_CLICKED,PAGE_LOADED,FILTER_CHANGED,GRAPH_EXPANDED,GRAPH_COLLAPSED,CONTENT_HEIGHT_CHANGED,EXTERNAL_URL(+ anUNKNOWNcase for forward compatibility). - Auto-height - the SDK injects a
ResizeObserverand sizes the widget to its content (autoHeight, default on, withminHeight/maxHeightconstraints) - no manual height management. - External link handling -
window.open(),target="_blank", and custom-scheme navigations are intercepted and routed to the system browser / native apps, which is what makes affiliate click-outs and app deep links work from inside a WebView. Handle or observe them viaonExternalUrl. - Device detection -
device_typeis seeded automatically from the platform (overridable viaextraParams), so the right app vs. web deep links are chosen without configuration.
Quick Starts
Flutter
dependencies:
odditt_flutter_sdk:
git:
url: https://github.com/Odditt-Betflow/odditt-flutter-sdk.git
ref: mainOddittWidget(
baseUrl: 'https://widget.example.com',
config: const OddittWidgetConfig(
country: 'US',
colorMode: 'dark',
layoutMode: 'carousel',
widgetMode: 'operator',
extraParams: {'preset': 'brand_dark_v2', 'lang': 'en-US'},
),
onBetClicked: (bet) => openBetSlip(bet),
onEmpty: () => hideWidgetSection(),
onError: (e) => hideWidgetSection(),
);React Native
npm install @odditt/react-native-sdk react-native-webview
# iOS: cd ios && pod install<OddittWidget
baseUrl="https://widget.example.com"
config={{ country: 'US', colorMode: 'dark', layoutMode: 'carousel' }}
onBetClicked={(bet) => openBetSlip(bet)}
onEmpty={() => setShowWidget(false)}
onError={() => setShowWidget(false)}
/>iOS (SwiftUI)
// SPM: .package(url: "https://github.com/Odditt-Betflow/odditt-ios-sdk.git", branch: "main")
OddittWidget(
baseUrl: "https://widget.example.com",
config: OddittWidgetConfig(country: "US", oddsFormat: "american"),
onBetClicked: { signal in openBetSlip(signal) }
)UIKit apps use OddittWidgetView with the same configuration.
Android (Compose)
// settings.gradle.kts: maven(url = "https://jitpack.io")
// build.gradle.kts: implementation("com.github.Odditt-Betflow:odditt-android-sdk:main-SNAPSHOT")
OddittWidget(
baseUrl = "https://widget.example.com",
config = OddittWidgetConfig(country = "US"),
onBetClicked = { bet -> openBetSlip(bet) }
)Requires the INTERNET permission. View-based apps use OddittWidgetView.
Handling Empty & Error States
The same rule as the web embed applies - never leave a blank widget in your layout. Wire onEmpty and onError to collapse the widget's container (auto-height already shrinks the widget itself, but your section chrome - headings, padding - is yours to hide). See Integration Recipes for the full pattern and the scoping guidance that avoids empty feeds in the first place.
Next Steps
- Iframe Parameters - everything
config+extraParamscan carry - Widget Events - payload reference for each signal
- Widget Modes - operator handoff vs. affiliate click-out behavior in-app
- Integration Recipes - production wiring patterns
Updated about 15 hours ago

