@aisahub/app-builder-sdk
v1.0.9
Published
WebView to Flutter communication bridge SDK for App Builder - Access native device capabilities from web applications
Readme
@aisahub/app-builder-sdk
WebView-to-Flutter communication bridge SDK that enables seamless integration between web applications and native Flutter functionality.
Features
- ✨ Native Integration - Access device capabilities like push notifications, secure storage, and location services
- 🔄 Bidirectional Communication - JavaScript-to-Flutter bridge via WebView channels
- 🌐 Graceful Degradation - Automatic fallback to web APIs when running in browsers
- 📘 TypeScript Support - Full type definitions included
- ⚛️ React Hooks - Pre-built hooks for React/Next.js applications
- 🪶 Zero Dependencies - Lightweight vanilla JavaScript core
- 🔊 Text-to-Speech - Native TTS with language management
Installation
npm install @aisahub/app-builder-sdkor
yarn add @aisahub/app-builder-sdkQuick Start
Vanilla JavaScript / HTML
Include the SDK in your HTML:
<script src="node_modules/@aisahub/app-builder-sdk/dist/app-builder-bridge.min.js"></script>
<script>
if (AppBridge.isInApp()) {
console.log('Running in app environment');
AppBridge.generateFcmToken((result) => {
if (result.success) {
console.log('FCM Token:', result.token);
}
});
}
</script>ES Modules / TypeScript
import '@aisahub/app-builder-sdk';
// AppBridge is now available globally
if (window.AppBridge.isInApp()) {
window.AppBridge.generateFcmToken((result) => {
console.log('Token:', result.token);
});
}React / Next.js
import { useAppBridge, useGenerateFcmToken } from '@aisahub/app-builder-sdk/hooks';
export default function MyComponent() {
const { isInApp, bridge } = useAppBridge();
const { generateToken, token, loading } = useGenerateFcmToken();
return (
<div>
<p>Environment: {isInApp ? 'App' : 'Web Browser'}</p>
<button onClick={generateToken} disabled={loading}>
{loading ? 'Generating...' : 'Get FCM Token'}
</button>
{token && <p>Token: {token}</p>}
</div>
);
}Core API
Environment Detection
AppBridge.isInApp() // Returns true if running in app environment (native or PWA)
AppBridge.isNativeApp() // Returns true if running in Flutter WebView
AppBridge.isPWA() // Returns true if running in PWA iframePush Notifications
AppBridge.generateFcmToken((result) => {
if (result.success) {
console.log('Token:', result.token);
}
});Secure Storage
// Save
AppBridge.saveSecure('auth_token', 'xyz123', (result) => {
console.log('Saved:', result.success);
});
// Get
AppBridge.getSecure('auth_token', (result) => {
console.log('Value:', result.value);
});
// Delete
AppBridge.deleteSecure('auth_token', (result) => {
console.log('Deleted:', result.success);
});Device Information
AppBridge.getDeviceInfo((info) => {
console.log(info);
// { model: "Pixel 6", manufacturer: "Google", osVersion: "13", platform: "android" }
});
AppBridge.getAppVersion((info) => {
console.log(info);
// { version: "1.2.3", buildNumber: "42" }
});Location Services
// Request permission
AppBridge.requestLocationPermission((result) => {
if (result.granted) {
// Get location
AppBridge.getCurrentLocation((location) => {
console.log(location.latitude, location.longitude);
});
}
});User Interactions
// Toast notification
AppBridge.showToast('Settings saved!', 'short');
// Vibration
AppBridge.vibrate(100);
// Share dialog
AppBridge.share('Check this out!', 'https://example.com', (result) => {
console.log('Shared:', result.success);
});
// Open external URL
AppBridge.openExternalUrl('https://example.com');
// Badge count
AppBridge.setBadgeCount(5);Authentication
AppBridge.logout((result) => {
if (result.success) {
window.location.href = '/login';
}
});Text-to-Speech
// Speak text - returns ttsId for tracking
const result = await AppBridge.speak('Hello world!', {
language: 'en-US',
rate: 0.5,
pitch: 1.0,
volume: 1.0
});
const ttsId = result.data.ttsId;
// Wait for speech to complete (non-blocking)
// Call this in background, don't await in UI thread
AppBridge.isTtsComplete(ttsId).then(() => {
console.log('Speech finished!');
});
// Cancel speech
await AppBridge.cancelSpeech();
// Get available languages
const langResult = await AppBridge.getTTSLanguages();
console.log(langResult.data.languages); // ['en-US', 'es-ES', ...]
// Check language availability
const available = await AppBridge.isTTSLanguageAvailable('en-US');
// Open TTS settings (to install languages)
await AppBridge.openTTSSettings();React Hooks
useAppBridge()
Initialize and access the AppBridge instance:
import { useAppBridge } from '@aisahub/app-builder-sdk/hooks';
const { bridge, isReady, isInApp, isNativeApp, isPWA } = useAppBridge();useGenerateFcmToken()
Manage FCM token generation with loading states:
import { useGenerateFcmToken } from '@aisahub/app-builder-sdk/hooks';
const { generateToken, token, loading, error } = useGenerateFcmToken();useDeviceInfo()
Fetch device information:
import { useDeviceInfo } from '@aisahub/app-builder-sdk/hooks';
const { deviceInfo, loading } = useDeviceInfo();useAppVersion()
Get app version information:
import { useAppVersion } from '@aisahub/app-builder-sdk/hooks';
const { version, loading } = useAppVersion();useSecureStorage()
Promise-based secure storage operations:
import { useSecureStorage } from '@aisahub/app-builder-sdk/hooks';
const { saveSecure, getSecure, deleteSecure } = useSecureStorage();
// Usage
const saved = await saveSecure('key', 'value');
const value = await getSecure('key');
const deleted = await deleteSecure('key');useTTS()
Text-to-Speech with language management:
import { useTTS } from '@aisahub/app-builder-sdk/hooks';
const {
speak,
cancel,
speaking,
getLanguages,
availableLanguages,
isLanguageAvailable,
openSettings
} = useTTS();
// Usage
await speak('Hello!', { language: 'en-US', rate: 0.5 });
await cancel();
await getLanguages(); // populates availableLanguagesTypeScript Support
The SDK includes full TypeScript definitions:
import type {
AppBridgeAPI,
FcmTokenResult,
DeviceInfo,
LocationResult
} from '@aisahub/app-builder-sdk';
declare global {
interface Window {
AppBridge: AppBridgeAPI;
}
}Platform Support
- ✅ iOS (via Flutter WebView)
- ✅ Android (via Flutter WebView)
- ✅ Web Browsers (with graceful fallback to web APIs)
Documentation
Examples
Authentication Flow
async function loginUser(email, password) {
// Authenticate with backend
const response = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify({ email, password })
});
const { authToken } = await response.json();
// Save token securely
AppBridge.saveSecure('auth_token', authToken, (result) => {
if (result.success) {
// Get FCM token for push notifications
AppBridge.generateFcmToken((fcmResult) => {
if (fcmResult.success) {
registerDeviceWithBackend(fcmResult.token);
}
});
AppBridge.showToast('Login successful!');
window.location.href = '/dashboard';
}
});
}Location-Based Features
function findNearbyStores() {
AppBridge.requestLocationPermission((permissionResult) => {
if (permissionResult.granted) {
AppBridge.getCurrentLocation((location) => {
if (location.latitude) {
fetch(`/api/stores/nearby?lat=${location.latitude}&lng=${location.longitude}`)
.then(res => res.json())
.then(stores => {
AppBridge.showToast(`Found ${stores.length} stores nearby`);
});
}
});
}
});
}Security
- 🔒 Secure Storage: Uses iOS Keychain and Android EncryptedSharedPreferences
- 🔐 HTTPS Only: Always serve your app over HTTPS
- ✅ Input Validation: All inputs are validated before processing
Changelog
[1.0.8] - 2025-12-10
- Fixed TTS completion tracking loop issue
- Changed
isTtsComplete()to event-based pattern (no polling/callbacks) - PWA/Flutter now sends
TTS_COMPLETEDevent when speech finishes - Added
handleTtsCompleted(ttsId)global handler for Flutter
[1.0.7] - 2025-12-10
- Added
isTtsComplete(ttsId)method to track speech completion speak()now returnsttsIdfor tracking when speech finishes- Updated
useTTS()hook to automatically track speech completion state - Documentation and examples updated with non-blocking completion pattern
[1.0.6] - 2025-12-10
- Added Text-to-Speech (TTS) support with
speak()andcancelSpeech()methods - Customizable TTS options: language, rate, pitch, and volume
- TTS language management:
getTTSLanguages(),isTTSLanguageAvailable(),isTTSLanguageInstalled(),openTTSSettings() - New
useTTS()React hook with full language management support
[1.0.5] - 2025-12-10
- Fixed synchronous PWA detection via
window.namefor immediate environment detection - Improved reliability of
isInApp()check in PWA contexts
[1.0.4] - 2025-12-09
- Added PWA (Progressive Web App) support with iframe environment detection
- New
isPWA()method to detect PWA iframe environment isInApp()now returns true for both native apps and PWA environments- Fixed SDK cache invalidation issues
[1.0.3] - 2025-11-15
- Restructured documentation table of contents
- Separated authentication section for login functionality
[1.0.2] - 2025-11-10
- Fixed callback data handling for improved reliability
- Added comprehensive debugging capabilities
[1.0.1] - 2025-11-05
- Implemented Result interface for consistent API responses
- Converted SDK methods to async/await pattern
[1.0.0] - 2025-10-27
- Initial release with full WebView-to-Flutter bridge functionality
See CHANGELOG.md for full details.
Contributing
Contributions are welcome! Please read our Contributing Guide for details.
License
MIT © AISA Hub
Support
- 🐛 Report Issues
- 💬 Discussions
- 📧 Email: [email protected]
Made with ❤️ by AISA Hub
