Products
UI Widgets
Overview
Our UI Widgets offer a suite of components designed to enrich your application with insightful health information. By integrating our UI Widgets into your app, you provide your users with valuable health insights derived from their activity and wellness data.
Get started with UI Widgets
Key Features
-
Seamless Integration : UI Widgets are designed for easy integration into any mobile application, providing a smooth and cohesive user experience.
-
User Engagement : Engage users with interactive and visually appealing widgets that present health insights in an intuitive and accessible manner.
-
Data-Driven Insights : UI widgets offer valuable insights from processed health data, empowering users with the knowledge to understand and improve their well-being.
-
Cross-Platform Compatibility : With support for iOS, Android, Flutter, and React Native, our widgets ensure a wide-reaching and versatile application across various devices and platforms.
-
Customizable Presentation (Coming Soon) : Tailor the appearance and functionality of the widgets to align with your app's design and user needs, ensuring a consistent and branded experience.
How It Works
Simply use our webview component and call one of our UI Widget endpoints with the profile token provided by our SDK. Instantly, you'll receive a dynamic and interactive chart that suits your needs. Whether you want to display a Score Chart, Score Arc, or Factor List, our widgets make it easy to present valuable insights in a visually appealing way.
Available Widgets
Widgets come in two types - pages and components.
Widget Pages
Widget pages are larger, comprehensive widgets that include a variety of widget components.

Scores Page
The Scores Page widget visually represents an overview of all scores for the current day along with a date selector for browsing historical scores.
URL
https://webview.sahha.ai/app
URL with date
https://webview.sahha.ai/app?date=2024-05-20
Widget Components
Widget components are smaller, more modular widgets that can present target data in a compact way.
You can choose from a variety of styles to present target:
- Score Chart : Show scores values in a 7 day chart
- Score Arc : Show score values in a sleek, semicircular gauge
- Score Bar : Show scores values in a progressive, horizontal gauge
- Factor List : Show scores factors in an organized list
See below for examples of each style.
Activity Score chart
The Score Chart widget provides a clear visual representation of scores over the last 7 days. Each bar corresponds to a day's score, with the most recent day displayed on the right. This intuitive layout helps you easily track and compare daily performance trends. Perfect for monitoring progress, analyzing patterns, and making data-driven decisions at a glance.
URL
https://webview.sahha.ai/score/activity/chart
URL with date
https://webview.sahha.ai/score/activity/chart?date=2024-05-20
Activity Score Arc
The Score Arc widget visually represents a score within a semi-circle arc. It dynamically displays a numeric score at the center of the arc along with its current state. This intuitive design makes it easy to quickly gauge performance or status at a glance. Ideal for dashboards, reports, and any application where you need a clear, concise visual representation of a score.
URL
https://webview.sahha.ai/score/activity/arc
URL with date
https://webview.sahha.ai/score/activity/arc?date=2024-05-20
Activity Score Bar
The Score Bar widget visually represents a score within a linear bar. It dynamically displays a numeric score at the top of the bar along with its current state. This intuitive design makes it easy to quickly gauge performance or status at a glance. Ideal for dashboards, reports, and any application where you need a clear, concise visual representation of a score.
URL
https://webview.sahha.ai/score/activity/bar
URL with date
https://webview.sahha.ai/score/activity/bar?date=2024-05-20
Activity Factors
The Factors widget offers a detailed list of factors that contributed to determining a score. Each factor is clearly listed, providing transparency and insight into the scoring process. This component is designed to help users understand the underlying reasons behind their scores, fostering trust and enabling more informed decision-making.
URL
https://webview.sahha.ai/score/activity/factors
URL with date
https://webview.sahha.ai/score/activity/factors?date=2024-05-20
Factor score as percentage
https://webview.sahha.ai/score/activity/factors?percentage=true
Integration Guide
Follow this guide to easily add UI Widgets directly into your project. Choose your platform:
iOS
You can show a webview in your UIKit or SwiftUI project.
UIKit
Use a WKWebView
If your project uses UIKit views, you will need to create and display a WKWebView .
// WebViewController.swift
import UIKitimport WebKitimport Sahha
class WebViewController: UIViewController, WKUIDelegate {
var webView: WKWebView!
override func loadView() { let webConfiguration = WKWebViewConfiguration() webView = WKWebView(frame: .zero, configuration: webConfiguration) webView.uiDelegate = self view = webView }
override func viewDidLoad() { super.viewDidLoad()
// Use https://webview.sahha.ai/app in production
if let url = URL(string: "https://sandbox.webview.sahha.ai/app") { var request = URLRequest(url: url) if let authToken = Sahha.profileToken { request.setValue(authToken, forHTTPHeaderField: "Authorization") } webView.load(request) }
}
}
SwiftUI
Use a UIViewRepresentable and WKWebview
If your project uses SwiftUI views, you will need to create and display a UIViewRepresentable and WKWebview .
Step 1) Create the UIViewRepresentable
View the SwiftUI - UIViewRepresentable guide.
// WebView.swift
import SwiftUIimport WebKit
struct WebView: UIViewRepresentable {
let urlString: String var profileToken: String?
func makeUIView(context: Context) -> WKWebView {
let webview = WKWebView() webview.isMultipleTouchEnabled = false return webview }
func updateUIView(_ webView: WKWebView, context: Context) {
if let url = URL(string: urlString) { var request = URLRequest(url: url)
// Add authorization if let authToken = profileToken { request.setValue(authToken, forHTTPHeaderField: "Authorization") }
webView.load(request) } }
}
Step 2) Display the UIViewRepresentable in a SwiftUI view
View the WebKit - WKWebview guide.
// ContentView.swift
import SwiftUIimport Sahha
struct ContentView: View {
var body: some View {
// Use https://webview.sahha.ai/app in production
WebView(urlString: "https://sandbox.webview.sahha.ai/app", profileToken: Sahha.profileToken)
}}
Android
Use a WebView
You will need to create and display a WebView .
AndroidView( factory = { WebView(context).apply { val cookieManager = CookieManager.getInstance() cookieManager.setAcceptCookie(true) cookieManager.setAcceptThirdPartyCookies(this, true)
layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT )
webViewClient = WebViewClient()
settings.apply { javaScriptEnabled = true domStorageEnabled = true databaseEnabled = true cacheMode = WebSettings.LOAD_DEFAULT }
// Use https://webview.sahha.ai/app in production
val webViewUrl = "https://sandbox.webview.sahha.ai/app" Sahha.profileToken?.also { token -> loadUrl(webViewUrl, mapOf("Authorization" to token)) } ?: loadUrl(webViewUrl)
} },)
Flutter
Use a WebView
You will need to create and display a WebView .
Step 1) Add webview_flutter as a dependency in your pubspec.yaml file
dependencies: flutter: sdk: flutter
webview_flutter: ^4.7.0
Step 2) Instantiate a WebViewController
View the Flutter WebViewController guide.
Step 3) Pass the controller to a WebViewWidget
View the Flutter WebViewWidget guide.
import 'package:flutter/material.dart';import 'package:sahha_flutter/sahha_flutter.dart';
import 'package:webview_flutter/webview_flutter.dart';// Import for Android featuresimport 'package:webview_flutter_android/webview_flutter_android.dart';// Import for iOS featuresimport 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
class WebView extends StatefulWidget { const WebView({Key? key}) : super(key: key);
WebState createState() => WebState();}
class WebState extends State<WebView> { late final WebViewController _controller;
void initState() { super.initState();
// #docregion platform_features late final PlatformWebViewControllerCreationParams params; if (WebViewPlatform.instance is WebKitWebViewPlatform) { params = WebKitWebViewControllerCreationParams( allowsInlineMediaPlayback: true, mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{}, ); } else { params = const PlatformWebViewControllerCreationParams(); }
final WebViewController controller = WebViewController.fromPlatformCreationParams(params);
controller ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setBackgroundColor(const Color(0x00000000)) ..setNavigationDelegate( NavigationDelegate( onProgress: (int progress) { debugPrint('WebView is loading (progress : $progress%)'); }, onPageStarted: (String url) { debugPrint('Page started loading: $url'); }, onPageFinished: (String url) { debugPrint('Page finished loading: $url'); }, onWebResourceError: (WebResourceError error) { debugPrint('''Page resource error: code: ${error.errorCode} description: ${error.description} errorType: ${error.errorType} isForMainFrame: ${error.isForMainFrame} '''); }, onNavigationRequest: (NavigationRequest request) { if (request.url.startsWith('https://www.youtube.com/')) { debugPrint('blocking navigation to ${request.url}'); return NavigationDecision.prevent; } debugPrint('allowing navigation to ${request.url}'); return NavigationDecision.navigate; }, onHttpError: (HttpResponseError error) { debugPrint('Error occurred on page: ${error.response?.statusCode}'); }, onUrlChange: (UrlChange change) { debugPrint('url change to ${change.url}'); }, onHttpAuthRequest: (HttpAuthRequest request) { debugPrint('auth request $request'); }, ), )
// #docregion platform_features if (controller.platform is AndroidWebViewController) { AndroidWebViewController.enableDebugging(true); (controller.platform as AndroidWebViewController) .setMediaPlaybackRequiresUserGesture(false); } // #enddocregion platform_features
_controller = controller;
SahhaFlutter.getProfileToken().then((value) { debugPrint(value); if (value != null) { controller.loadRequest(
// Use https://webview.sahha.ai/app in production
Uri.parse("https://sandbox.webview.sahha.ai/app"), headers: {"Authorization": value}, ); } else { controller.loadRequest(
// Use https://webview.sahha.ai/app in production
Uri.parse("https://sandbox.webview.sahha.ai/app"), ); } }).catchError((error, stackTrace) { debugPrint(error.toString()); }); }
Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Webview Example')), body: WebViewWidget(controller: _controller), ); }
}
React Native
Use a WebView
You will need to create and display a WebView .
Step 1) Install react-native-webview via npm
npm install react-native-webview
Step 2) Instantiate a WebViewController
import React, { Component } from 'react';import { WebView } from 'react-native-webview';import Sahha from 'sahha-react-native';
const MyWebComponent = () => {
const [profileToken, setProfileToken] = useState<string>('');
useEffect(() => { Sahha.getProfileToken((error: string, token?: string) => { if (error) { console.error(`Error: ${error}`); } else if (token) { console.log(`Profile Token: ${token}`); setProfileToken(token); } else { console.log(`Profile Token: null`); } }); }, []);
// Use https://webview.sahha.ai/app in production
return <WebView source={{ uri: "https://sandbox.webview.sahha.ai/app", headers: { 'Authorization': profileToken, }, }} style={{ flex: 1 }} />;}
Web
Use an HTML iFrame
You will need to create and display an HTML iFrame .
Route prefix required
When embedding webviews inside of an iFrame, all route names must be prefixed with /web
.
For example, to use the sleep chart widget, the URL should be: https://webview.sahha.ai/web/score/sleep/chart
<!doctype html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Sahha UI Widget Example</title> <script> // You will need to authenticate your user profile via the Sahha SDK or API // Once you receive a profile token, set it here const profileToken = 'PROFILE_TOKEN'; // Replace 'PROFILE_TOKEN' with the real profile token
// Origin for the webview // Use 'https://webview.sahha.ai' for your production app const origin = 'https://sandbox.webview.sahha.ai';
// The source URL for the iFrame // This should be the full URL of the Sahha widget you want to render inside the iFrame. // The URL must use the same `origin` as defined above to ensure proper communication between the parent page and the iFrame. const source = origin + '/web/app'; // Example widget path: "/web/app"
// Event listener for message event window.addEventListener('message', (event) => { if (event.origin !== origin) return;
if (event.data.loaded) { event.source?.postMessage(profileToken, origin); } });
// Create and inject the iFrame into your HTML page document.addEventListener('DOMContentLoaded', () => { const iframe = document.createElement('iframe');
iframe.src = source; iframe.title = 'Sahha Webview'; iframe.style.width = '100%'; iframe.style.height = '1000px'; iframe.style.border = 'none';
document.body.appendChild(iframe); }); </script> </head> <body></body></html>