Bridge API Reference

Complete reference for window.LoadSites — the native bridge available to all CWA apps.

Overview

The bridge is a JavaScript API embedded inline before your app's scripts run, so window.LoadSites is available immediately. All async methods return Promises that resolve with the result or reject with an error.

The bridge operates through an asynchronous message-passing protocol between your JavaScript (running in the platform's WebView sandbox) and the container's native layer. Every API call is validated against the app's declared and user-approved permissions. The bridge does not expose raw platform APIs — all native functionality is mediated through a predefined, permission-gated API surface.

Global Properties

PropertyTypeDescription
LoadSites.version string Bridge version (e.g., "1.1.0").
LoadSites.domain string The domain this app was installed from.
LoadSites.appId string The app ID ("default" for single-app manifests).

Bridge Detection

// Immediate check (bridge loads before your scripts)
if (window.LoadSites) {
  console.log('CWA bridge v' + LoadSites.version);
}

// Event listener (safety net)
window.addEventListener('loadsites:ready', function(e) {
  console.log('Bridge ready:', e.detail);
});

// Callback (alternative)
window.onLoadSitesReady = function(bridge) {
  console.log('Ready:', bridge.domain, bridge.appId);
};

Haptics

Permission: haptics

LoadSites.haptics.vibrate(duration)

Vibrate the device for the specified duration in milliseconds.

ParamTypeDescription
durationnumberDuration in ms (e.g., 200)
await LoadSites.haptics.vibrate(200);

LoadSites.haptics.impact(style)

Trigger an impact haptic feedback.

ParamTypeValues
stylestring"light", "medium", "heavy"
await LoadSites.haptics.impact('medium');

LoadSites.haptics.notification(type)

Trigger a notification-style haptic.

ParamTypeValues
typestring"success", "warning", "error"
await LoadSites.haptics.notification('success');

Camera

Permission: camera

LoadSites.camera.takePhoto(options?)

Open the native camera to capture a photo. Returns a base64 data URI.

ParamTypeDescription
optionsobjectOptional. Camera configuration.
const photo = await LoadSites.camera.takePhoto();
// photo = { dataUrl: 'data:image/jpeg;base64,...', format: 'jpeg' }

LoadSites.camera.pickFromGallery(options?)

Open the photo gallery picker. Returns a base64 data URI.

const image = await LoadSites.camera.pickFromGallery();
document.getElementById('preview').src = image.dataUrl;

Microphone

Permission: microphone

LoadSites.microphone.requestPermission()

Request microphone access from the OS.

LoadSites.microphone.startRecording()

Begin audio recording.

LoadSites.microphone.stopRecording()

Stop recording and return the audio data.

await LoadSites.microphone.requestPermission();
await LoadSites.microphone.startRecording();

// Later...
const recording = await LoadSites.microphone.stopRecording();
// recording = { dataUrl: 'data:audio/...', duration: 5200 }

Geolocation

Permission: geolocation

LoadSites.geolocation.getCurrentPosition(options?)

Get the device's current GPS position.

const pos = await LoadSites.geolocation.getCurrentPosition();
// pos = { latitude: 37.7749, longitude: -122.4194, accuracy: 10 }

LoadSites.geolocation.watchPosition(callback, options?)

Start watching for position changes. The callback fires on each update.

const watch = await LoadSites.geolocation.watchPosition(function(pos) {
  console.log('New position:', pos.latitude, pos.longitude);
});

// Later: stop watching
await LoadSites.geolocation.clearWatch(watch.watchId);

LoadSites.geolocation.clearWatch(watchId)

Stop a position watch started by watchPosition.

Notifications

Permission: notifications License Required

See the dedicated Notifications page for the full guide including server-side sending and in-app handling.

LoadSites.notifications.getDeviceKey()

Get the unique device key used to target this device for push notifications.

const result = await LoadSites.notifications.getDeviceKey();
// result = { deviceKey: 'abc123-def456-...' }
// Send this key to your server to target this device

LoadSites.notifications.requestPermission()

Request push notification permission from the user.

const result = await LoadSites.notifications.requestPermission();
// result = { granted: true }

LoadSites.notifications.isAllowed()

Check whether notifications are currently allowed for this app.

const result = await LoadSites.notifications.isAllowed();
if (result.allowed) {
  console.log('Notifications are enabled');
}

LoadSites.notifications.onNotification(callback)

Register a callback for notifications received while the app is in the foreground. When a push notification arrives and the app is open, the container forwards it directly to the app instead of showing a system notification.

LoadSites.notifications.onNotification(function(notification) {
  // notification = { title: '...', body: '...', data: { ... } }
  showInAppToast(notification.title, notification.body);
});

LoadSites.notifications.offNotification(callback)

Remove a previously registered notification callback.

Device

Permission: device

LoadSites.device.getInfo()

Get device hardware and software information.

const info = await LoadSites.device.getInfo();
// info = {
//   model: 'iPhone 15 Pro',
//   platform: 'ios',
//   operatingSystem: 'ios',
//   osVersion: '17.4',
//   manufacturer: 'Apple',
//   isVirtual: false
// }

LoadSites.device.getPlatform()

Get the current platform.

const result = await LoadSites.device.getPlatform();
// result = { platform: 'ios' }  // or 'android', 'web'

Storage

Permission: storage

Persistent key-value storage scoped to your domain and app ID. Data persists across app restarts and updates.

LoadSites.storage.get(key)

const result = await LoadSites.storage.get('user_prefs');
// result = { value: '{"theme":"dark","lang":"en"}' }
const prefs = JSON.parse(result.value);

LoadSites.storage.set(key, value)

await LoadSites.storage.set('user_prefs', JSON.stringify({
  theme: 'dark',
  lang: 'en'
}));

LoadSites.storage.remove(key)

await LoadSites.storage.remove('user_prefs');

LoadSites.storage.keys()

const result = await LoadSites.storage.keys();
// result = { keys: ['user_prefs', 'session_token', 'cache_v2'] }

LoadSites.storage.clear()

Remove all stored data for this app.

await LoadSites.storage.clear();
Storage isolation

Storage is scoped to domain + appId. Two apps from the same domain cannot access each other's data. Storage keys are prefixed internally as domain::appId::key.

Share

Permission: share

LoadSites.share.share(options)

Open the native share sheet.

ParamTypeDescription
options.titlestringShare title
options.textstringShare text content
options.urlstringURL to share
await LoadSites.share.share({
  title: 'Check this out',
  text: 'An awesome CWA app!',
  url: 'https://example.com'
});

Clipboard

Permission: clipboard

LoadSites.clipboard.write(text)

await LoadSites.clipboard.write('Copied text!');

LoadSites.clipboard.read()

const result = await LoadSites.clipboard.read();
// result = { value: 'Copied text!' }

Biometrics

Permission: biometrics

LoadSites.biometrics.isAvailable()

Check if biometric authentication is available on this device.

const result = await LoadSites.biometrics.isAvailable();
// result = { available: true, type: 'face' }  // or 'fingerprint'

LoadSites.biometrics.authenticate(reason)

Prompt the user for biometric authentication.

try {
  const result = await LoadSites.biometrics.authenticate('Confirm your identity');
  // result = { verified: true }
  console.log('Authentication successful');
} catch (err) {
  console.log('Authentication failed:', err.message);
}

Network

Permission: network

LoadSites.network.getStatus()

Get the current network connectivity status.

const status = await LoadSites.network.getStatus();
// status = { connected: true, connectionType: 'wifi' }

LoadSites.network.onStatusChange(callback)

Listen for network connectivity changes.

await LoadSites.network.onStatusChange(function(status) {
  if (!status.connected) {
    showOfflineBanner();
  } else {
    hideOfflineBanner();
  }
});

No permission required.

The navigation API lets your app interact with the LoadSites container UI.

LoadSites.navigation.close()

Close the current app and return to the LoadSites home screen.

LoadSites.navigation.close();

LoadSites.navigation.home()

Navigate to the LoadSites home screen (same as close()).

LoadSites.navigation.switchTo(domain, appId?)

Switch to another installed app.

// Switch to a specific app
LoadSites.navigation.switchTo('acme.com', 'calendar');

// Switch to a single-app domain (appId defaults to 'default')
LoadSites.navigation.switchTo('other-site.com');

LoadSites.navigation.showMenu()

Programmatically open the exit/app-switch overlay. This is the same overlay triggered by the swipe-down gesture from the top-right corner.

// Add a menu button to your app
document.getElementById('menu-btn').addEventListener('click', function() {
  LoadSites.navigation.showMenu();
});

Error Handling

All bridge methods return Promises. If a request fails (permission denied, timeout, or native error), the Promise rejects with an Error:

try {
  const photo = await LoadSites.camera.takePhoto();
  handlePhoto(photo);
} catch (err) {
  if (err.message === 'Bridge request timed out') {
    showRetryPrompt();
  } else {
    console.error('Camera error:', err.message);
  }
}

Requests that do not receive a response within 30 seconds are automatically timed out.