Push Notifications

Send real-time notifications to users via the LoadSites Cloud relay. Handle notifications both as system alerts and in-app events.

License required

Push notifications require a LoadSites license (Basic tier or higher). The notification relay infrastructure is managed by LoadSites Cloud. See Licensing below for tier details.

Architecture

Your Server                  LoadSites Cloud              User's Device
┌──────────┐    HTTP POST    ┌──────────────────┐   APNS   ┌──────────────────┐
│           │ ─────────────► │                  │ / FCM   │  LoadSites App   │
│  Backend  │                │  Notification    │ ───────► │  ┌────────────┐  │
│  Server   │   device_key   │  Relay Service   │          │  │ Your CWA   │  │
│           │  + license_key │                  │          │  │ App        │  │
└──────────┘                 └──────────────────┘          │  └────────────┘  │
                                                           └──────────────────┘
  1. Your app requests a device key via the bridge.
  2. You send the device key to your backend server.
  3. Your server sends notifications to the LoadSites Cloud API using the device key + your license key.
  4. LoadSites Cloud delivers via APNS (iOS) or FCM (Android) — the standard platform push channels.
  5. The LoadSites container shows a system notification or forwards it to the open app.
Standard platform channels

All push notifications flow through Apple's APNS and Google's FCM — the same infrastructure used by all native apps. The LoadSites container does not implement custom background networking, persistent sockets, or polling. This ensures compliance with platform battery and background execution policies.

Client-Side Setup

Three steps to enable notifications in your CWA app:

Step 1: Declare the Permission

Add "notifications" to your manifest's permissions array:

{
  "permissions": ["notifications", "haptics", "storage"]
}

Step 2: Request Permission & Get Device Key

async function setupNotifications() {
  // Request OS-level notification permission
  const perm = await LoadSites.notifications.requestPermission();
  if (!perm.granted) {
    console.log('User declined notifications');
    return;
  }

  // Get the unique device key for this installation
  const result = await LoadSites.notifications.getDeviceKey();
  const deviceKey = result.deviceKey;

  // Send the device key to your server
  await fetch('https://your-api.com/register-device', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ deviceKey: deviceKey })
  });

  console.log('Notifications registered with key:', deviceKey);
}

Step 3: Handle In-App Notifications

When a notification arrives while the app is open, the container forwards it to your app instead of showing a system notification. Register a handler:

// Listen for notifications received while app is in foreground
LoadSites.notifications.onNotification(function(notification) {
  // notification = {
  //   title: 'New Message',
  //   body: 'You have a message from Alice',
  //   data: { messageId: '123', sender: 'alice' }
  // }

  // Option A: Show an in-app toast
  showToast(notification.title, notification.body);

  // Option B: Update a badge count
  updateBadgeCount(notification.data);

  // Option C: Navigate to the relevant content
  if (notification.data.messageId) {
    navigateToMessage(notification.data.messageId);
  }
});
Foreground vs background

When the app is in the foreground, the notification is delivered to your onNotification callback and no system notification is shown. When the app is in the background or closed, a system notification is shown and tapping it opens the app.

Sending Notifications (Server-Side)

Send notifications from your backend server by POSTing to the LoadSites Cloud API:

Single Device

// Node.js example
const response = await fetch('https://cloud.loadsites.app/api/v1/notify', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_LICENSE_KEY'
  },
  body: JSON.stringify({
    device_key: 'target-device-key-here',
    domain: 'yourdomain.com',
    notification: {
      title: 'Order Shipped',
      body: 'Your order #1234 has shipped!',
      data: {
        orderId: '1234',
        status: 'shipped'
      }
    }
  })
});

Batch Sending

Send to multiple devices in a single request:

const response = await fetch('https://cloud.loadsites.app/api/v1/notify/batch', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_LICENSE_KEY'
  },
  body: JSON.stringify({
    domain: 'yourdomain.com',
    device_keys: [
      'device-key-1',
      'device-key-2',
      'device-key-3'
    ],
    notification: {
      title: 'System Update',
      body: 'Version 2.0 is now available',
      data: { version: '2.0.0' }
    }
  })
});

API Response

{
  "success": true,
  "delivered": 3,
  "failed": 0,
  "errors": []
}

Notification Object

FieldTypeStatusDescription
title string Required Notification title displayed to the user.
body string Required Notification body text.
data object Optional Custom key-value data payload. Delivered to onNotification callback and available when the user taps the notification.

Handling Notifications in Your App

In-App (Foreground)

Use onNotification to handle notifications when the user is actively using your app. Common patterns include:

// Complete example: in-app notification handling
LoadSites.notifications.onNotification(function(notification) {
  // Play haptic feedback
  LoadSites.haptics.notification('success');

  // Show a toast
  const toast = document.createElement('div');
  toast.className = 'in-app-toast';
  toast.innerHTML = '<strong>' + notification.title + '</strong><p>' + notification.body + '</p>';
  document.body.appendChild(toast);

  // Auto-dismiss after 4 seconds
  setTimeout(function() { toast.remove(); }, 4000);

  // Handle the data payload
  if (notification.data && notification.data.type === 'message') {
    updateMessageBadge();
  }
});

Background & Tap-to-Open

When the user taps a system notification to open the app, the notification data is available through the normal app launch flow. The container stores the most recent notification and delivers it via onNotification when the app initializes.

Unsubscribing

// Remove a specific callback
function myHandler(notification) { /* ... */ }
LoadSites.notifications.onNotification(myHandler);

// Later...
LoadSites.notifications.offNotification(myHandler);

Security Model

Push notifications are delivered through the platform's standard push infrastructure — Apple Push Notification Service (APNS) on iOS and Firebase Cloud Messaging (FCM) on Android. The LoadSites Cloud relay forwards notifications through these official channels; no custom background networking or persistent connections are used. This architecture complies with Apple and Google platform policies for push notification delivery.

Best Practices

Licensing

Push notifications are the only CWA feature that requires a paid license. The license key is included in your manifest (license_key field) and used to authenticate Cloud API calls.

TierMonthly PriceNotifications / MonthFeatures
Free $0 0 All bridge APIs except notifications
Basic $9 10,000 Push notifications, email support
Pro $29 100,000 Push notifications, priority support, analytics dashboard
Enterprise Custom Unlimited Custom SLA, dedicated infrastructure, white-label option
All other features are free

Camera, haptics, biometrics, geolocation, storage, share, clipboard, network, device info, and navigation — all available at no cost, no license needed.

Troubleshooting

Notifications not arriving

onNotification not firing