JavaScript Bridge
Your website can call a few native features directly. The app injects a global window.AppForge object into your own pages, so the same site keeps working untouched in a normal browser — just feature-detect it:
if (window.AppForge) {
// running inside the app
}
The bridge is only injected into pages on your domain. A third-party site opened through an allow-listed domain never receives it, so it cannot read your push token or change notification settings.
Detecting the app
if (window.AppForge && window.AppForge.isApp) {
document.body.classList.add('in-app'); // e.g. hide your own "download our app" banner
}
// If your script runs before the bridge is ready:
window.addEventListener('appforge:ready', function () {
console.log('Platform:', window.AppForge.platform); // "android" or "ios"
});
| Property | Value |
|---|---|
AppForge.isApp | always true inside the app |
AppForge.version | bridge version (currently 1) |
AppForge.platform | "android" or "ios" |
AppForge.appVersion | your app's name as configured in the panel |
Methods
Every method returns a Promise.
share(text, url)
Opens the native share sheet.
await AppForge.share('Check this out', location.href);
track(event)
Records one anonymous counter. Only the events the Analytics page understands are accepted (app_open, screen_view, webview_load, push_open, share, download, external_link, error); anything else is ignored.
await AppForge.track('screen_view');
pushToken()
The device's FCM token, so you can bind it to your own user record.
const { token } = await AppForge.pushToken();
if (token) {
await fetch('/api/save-push-token', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ token })
});
}
Returns {token: null} when Firebase is not configured or the user opted out.
notificationsEnabled() / setNotificationsEnabled(on)
Read or change the user's notification preference from your own settings page.
const { enabled } = await AppForge.notificationsEnabled();
await AppForge.setNotificationsEnabled(!enabled);
unreadCount()
How many messages are in the in-app inbox.
const { count } = await AppForge.unreadCount();
vibrate()
A short haptic tap — useful for confirming an action.
await AppForge.vibrate();
Notes
- Calls are ignored on pages outside your domain, so guard with
window.AppForge. - Nothing here can read files, contacts or location. The bridge exposes exactly the methods listed above and nothing else.
- Adding your own methods means editing
lib/features/webview/js_bridge.dart(register the handler) and the_shimstring in the same file (expose it to JavaScript). Keep the two in sync.