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"
});
PropertyValue
AppForge.isAppalways true inside the app
AppForge.versionbridge version (currently 1)
AppForge.platform"android" or "ios"
AppForge.appVersionyour 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 _shim string in the same file (expose it to JavaScript). Keep the two in sync.