B
Breacher API
Live Chat & Push
Full API Reference & Specifications

Breacher API Documentation

Complete specification for the Breacher serverless platform. Build lightweight apps with Git-backed document collections, atomic folder & file deletions, native TLS Gmail SMTP delivery, and zero-dependency identity management.

Base URL:https://storage.breacher.name.ng
Active & CORS Enabled
Core Operational Rules

Quick Start & Important Rules

Before using the API, keep these fundamental concepts in mind:

One-Time Setup

Your developer credentials and service access are configured once during onboarding. No periodic re-authentication is required.

Init Repo Once Only

You do NOT need to call initRepo() on every app run. Only call it when creating a brand new repository.

No Repo for Email

Sending transactional email via POST /:uid/mail connects via SMTP socket and requires no Git repository.

Architecture & Connectivity

Overview & Base URL

Breacher executes on Cloudflare Workers edge nodes, bridging three core subsystems:

GitDB NoSQL

JSON documents, collections, and binary assets committed into private GitHub repos with automatic SHA conflict resolution and edge caching.

Sockets Gmail SMTP

Connects directly to smtp.gmail.com:465 over raw TLS sockets for instant transactional email delivery.

PBKDF2 Auth Layer

100,000 round salted PBKDF2 hashing, HMAC indexed email lookups, and HttpOnly SameSite=None secure session cookies.

Client SDK
/sdk.js

Breacher JS SDK

Import the zero-dependency Breacher SDK directly into your web applications, scripts, or serverless functions.

Standard Client Setup (Remote Import)
// Direct fetch() API (No client class needed)
const BASE = "https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db";

// 1. User Registration: POST /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/auth/register
const regRes = await fetch(`${BASE}/auth/register`, {
  method: "POST",
  credentials: "include",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "user@example.com",
    password: "SecurePassword123!",
    name: "Alex Doe"
  })
});
const regData = await regRes.json();
console.log("Registered:", regData);

// 2. User Login: POST /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/auth/login
const loginRes = await fetch(`${BASE}/auth/login`, {
  method: "POST",
  credentials: "include",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "user@example.com",
    password: "SecurePassword123!"
  })
});
const loginData = await loginRes.json();
console.log("Logged in session:", loginData);
Access Control

Feature Configuration & Domain Restrictions

Breacher verifies developer privileges automatically. You can also configure project-level rules such as authorized browser origins.

Service Permissions
Mailing Service: Enabled for dispatching emails via high-speed Sockets SMTP.
GitDB Database: Enabled for performing NoSQL repository operations.
Auth Engine: Enabled for registering users and managing sessions.
Project Domain Restrictions
authorizedDomains: ["myapp.com"] - Restricts API requests to authorized browser origins.
authLimit: 100 - Maximum allowed registered user count for the project.
email_signin: false - Restricts sign-in method to OAuth only.
Communication
POST /:uid/mail

Mail API & SMTP Aliases

Connects directly to smtp.gmail.com:465 over raw TLS sockets. Supports rich HTML, fallback plaintext, preview preheaders, and sender aliases. Does not require a GitDB repository.

FieldTypeStatusDescription
to
stringRequiredRecipient email address (e.g. user@example.com).
subject
stringRequiredEmail subject line. UTF-8 Base64 encoded by the worker so emojis and special characters render cleanly.
from
or fromEmailaliasEmail
stringOptionalCustom sender address or configured Google Workspace alias.
Default: Your configured google_mail in Firebase
aliasName
or fromName
stringOptionalThe display name shown in the recipient inbox (e.g. 'Support Team').
alias
stringOptionalShorthand field: treated as fromEmail if it contains '@', or aliasName otherwise.
html
stringOptionalRich HTML email body. Allows inline styles, buttons, and layouts.
text
stringOptionalPlaintext fallback body if HTML is omitted.
preview
stringOptionalInbox preheader text shown in Gmail / Apple Mail message previews.
Sending an Email
// POST /U6op8Nr462Z46tBgxa2COUnja5z1/mail -> Direct fetch to Sockets Gmail SMTP
const res = await fetch("https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/mail", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    to: "customer@example.com",
    subject: "Order Confirmation #4092",
    from: "orders@myapp.com",
    aliasName: "Acme Store",
    preview: "Thank you for your purchase!",
    html: "<div style='font-family:sans-serif;'><h1>Thank you!</h1><p>Your order is confirmed.</p></div>"
  })
});
const data = await res.json();
console.log(data);
Success Response (200 OK):
{
  "success": true,
  "message": "Email sent successfully",
  "detail": "250 2.0.0 OK",
  "logId": "d3b07384-d113-4674-8742-88f54128f7bb"
}
One-Time Provisioning
POST /:uid/:repo/init

Initialize GitDB Repository

Creates a private GitHub repository automatically under your connected GitHub account and registers the project. You only need to run this once per new database project.

Initialize GitDB Repository
// Run once when setting up a new database (POST /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/init)
const res = await fetch("https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/init", {
  method: "POST"
});
const data = await res.json();
console.log(data);
Document Operations
GETPUTPATCH

Documents: Create, Read, & Update

Store arbitrary JSON documents at any nested path (e.g., users/usr_123 or settings/global).

PUT /:uid/:repo/:path

Writes or replaces a document. Automatically sets createdAt (if new) and updatedAt ISO timestamps. Handles GitHub 409 SHA conflict retries automatically.

PATCH /:uid/:repo/:path

Performs a partial merge with the existing JSON document on GitHub, updating specified fields and refreshing updatedAt.

GET /:uid/:repo/:path

Retrieves the document. Responses are edge-cached for 60 seconds.

Creating, Fetching, and Patching Documents
const BASE = "https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db";

// 1. Create Document (PUT /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/:path)
await fetch(`${BASE}/products/item_99`, {
  method: "PUT",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ title: "Mechanical Keyboard", price: 149.99 })
});

// 2. Read Document (GET /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/:path)
const readRes = await fetch(`${BASE}/products/item_99`);
const product = await readRes.json();
console.log("Product:", product);

// 3. Partial Update (PATCH /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/:path)
await fetch(`${BASE}/products/item_99`, {
  method: "PATCH",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ price: 129.99 })
});
Deletion Engine
DELETE /:uid/:repo/:path

Deletion: Files, Folders, & Media

Breacher supports atomic deletion of individual JSON documents, entire folder directories with nested trees in a single Git commit, and binary media assets.

Single File / Doc

Deletes an exact file path or document. If .json is omitted, Breacher automatically looks up both the raw path and the .json file.

DELETE /:uid/:repo/users/usr_1
Folder / Directory

Recursively removes all files and subdirectories under the path atomically using Git Data Tree operations in one single commit.

DELETE /:uid/:repo/logs?type=folder
Media Asset

Deletes binary uploaded assets under the /media/* path prefix and purges Cloudflare edge CDN cache immediately.

DELETE /:uid/:repo/media/avatar.png
Folder Deletion Query Parameters & Triggers:

A folder deletion is triggered whenever any of the following are present:

  • Query parameter: ?type=folder or ?type=dir
  • Query parameter: ?recursive=true
  • Trailing slash in the URL path (e.g. DELETE /:uid/:repo/archives/)
  • Automatic directory detection if GitHub returns a directory tree for the path.
Deletion Examples (File, Folder, Media)
const BASE = "https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db";

// 1. Delete a single document / file (DELETE /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/:path)
const fileRes = await fetch(`${BASE}/users/usr_101`, { method: "DELETE" });
const fileData = await fileRes.json();
console.log(fileData);

// 2. Delete an entire folder recursively (DELETE /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/:folder?type=folder)
const folderRes = await fetch(`${BASE}/logs/archive?type=folder`, { method: "DELETE" });
const folderData = await folderRes.json();
console.log(`Deleted ${folderData.deletedCount} items:`, folderData.deletedPaths);

// 3. Delete a media asset (DELETE /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/media/:path)
await fetch(`${BASE}/media/uploads/photo.jpg`, { method: "DELETE" });
File Deletion Response (200 OK):
{
  "success": true,
  "message": "Deleted users/usr_101.json",
  "path": "users/usr_101.json",
  "type": "file",
  "commit": "a3f89012c..."
}
Folder Deletion Response (200 OK):
{
  "success": true,
  "message": "Deleted folder 'logs/archive' (14 items removed)",
  "path": "logs/archive",
  "type": "folder",
  "deletedCount": 14,
  "deletedPaths": [
    "logs/archive/2026-01.json",
    "logs/archive/sub/events.json"
  ],
  "commit": "b7e41189d..."
}
Collection Queries
GET /:uid/:repo/:collection

Collection Queries & Sorting

When querying a directory, Breacher reads all JSON documents in parallel, attaches the document key as _id, and applies server-side sorting and limiting.

ParameterTypeExampleDescription
sort
stringOptionalSorts documents by a field key and direction formatted as field:asc or field:desc (e.g. createdAt:desc or price:asc).
limit
integerOptionalLimits the maximum number of documents returned in the response.
Querying a Collection with Sorting & Limiting
// Query Collection (GET /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/:collection?sort=field:dir&limit=N)
const res = await fetch("https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/messages?sort=createdAt:desc&limit=25");
const data = await res.json();
console.log(`Found ${data.count} documents:`, data.documents);
Collection Response (200 OK):
{
  "count": 2,
  "path": "messages",
  "documents": [
    {
      "_id": "msg_002",
      "text": "Latest message",
      "createdAt": "2026-08-26T12:00:00.000Z",
      "updatedAt": "2026-08-26T12:00:00.000Z"
    },
    {
      "_id": "msg_001",
      "text": "First message",
      "createdAt": "2026-08-26T11:00:00.000Z",
      "updatedAt": "2026-08-26T11:00:00.000Z"
    }
  ]
}
Live Streaming
GET /:uid/:repo/stream/:path

Realtime Database Stream (SSE)

Provides native Server-Sent Events (text/event-stream). You can listen to a Collection (folder) to get an array of all documents, or listen to a Document (file) to get its specific fields. Any standard POST, PUT, or PATCH write to that path automatically triggers a real-time update to all subscribers.

Reading & Writing Realtime Streams
// 1. READ: Listen to a Collection (Folder) stream
const streamUrl = "https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/stream/messages";
const eventSource = new EventSource(streamUrl, { withCredentials: true });

eventSource.onmessage = (event) => {
  // When listening to a folder, the payload is an array of documents
  const data = JSON.parse(event.data);
  console.log("Live collection update. Total docs:", data.length);
  // Example data: [{ _id: "msg_1", text: "Hello", ... }, ...]
};

// 2. WRITE: Trigger a stream update by writing to the folder
// Just use standard HTTP POST/PUT/PATCH to the regular path (without /stream/)
async function sendMessage(text) {
  const docId = "msg_" + Date.now();
  await fetch(`https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/messages/${docId}`, {
    method: "PUT",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ 
      text: text,           // "text" is a field
      sender: "Alice",      // "sender" is a field
      createdAt: new Date().toISOString() 
    })
  });
  // The SSE eventSource above will instantly receive the updated array!
}

// Send a test message
sendMessage("Hello from Realtime Stream!");

// To stop listening:
// eventSource.close();
How Folders & Fields map to Streams:
  • Collections (Folders): If you connect to /stream/messages, you receive a JSON array of all documents inside the messages/ folder.
  • Documents (Files): If you connect to /stream/messages/doc1, you receive a JSON object of just that document.
  • Fields: Are the keys/values inside your JSON document (e.g. "text": "Hello").
  • Triggering Updates: You do NOT POST to /stream/.... You simply write to the normal endpoint (e.g., PUT /messages/doc1). The server detects the change and automatically pushes the new data down the stream.
Binary Storage
POST / GET / DELETE /:uid/:repo/media/*

Media & Binary Asset Storage

Upload images, videos, audio, or PDFs up to 10MB directly to your repository. Served with correct MIME headers and long-term CDN caching.

Uploading & Serving Media Assets
// 1. Upload File (POST /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/media/:path)
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];

const uploadPath = "uploads/" + Date.now() + "_" + file.name;
await fetch(`https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/media/${uploadPath}`, {
  method: "POST",
  headers: { "Content-Type": file.type || "application/octet-stream" },
  body: file
});

// 2. Direct Public Embed URL (GET /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/media/:path)
const mediaUrl = `https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/media/${uploadPath}`;
console.log("Media URL:", mediaUrl);

// 3. Delete Media Asset (DELETE /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/media/:path)
await fetch(mediaUrl, { method: "DELETE" });
Identity & Auth
POST /:uid/:repo/auth/*

User Registration & Login

Breacher includes a full user identity layer backed by GitHub storage. Registration uses an atomic Durable Object coordinator to guarantee unique email claims without race conditions. Passwords are hash-protected with PBKDF2-SHA256 (100,000 iterations). Sessions are stored in HttpOnly cookies.

Register, Login, & Logout
// Direct fetch calls sending actual HTTP requests to the worker endpoints
const BASE_AUTH = "https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/auth";

// 1. REGISTER -> POST https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/auth/register
const regRes = await fetch(`${BASE_AUTH}/register`, {
  method: "POST",
  credentials: "include", // CRITICAL for receiving session cookie
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "alice@example.com",
    password: "SecurePassword123!",
    name: "Alice Developer"
  })
});
const regData = await regRes.json();
console.log("Registered user:", regData.user);

// 2. LOGIN -> POST https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/auth/login
const loginRes = await fetch(`${BASE_AUTH}/login`, {
  method: "POST",
  credentials: "include", // Saves the HttpOnly session cookie in the browser
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "alice@example.com",
    password: "SecurePassword123!"
  })
});
const loginData = await loginRes.json();
console.log("Logged in user:", loginData.user);

// 3. LOGOUT -> POST https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/auth/logout
await fetch(`${BASE_AUTH}/logout`, {
  method: "POST",
  credentials: "include"
});

How to Keep Users Logged In (On-Boot / Refresh Check)

When a user logs in, the worker returns a secure breacher_session cookie (valid for 30 days). To keep the user logged in across page refreshes and browser restarts, send a GET /auth/me request with credentials: "include" when your frontend boots up:

Keep User Logged In on Page Load (Fetch & Framework Patterns)
// Standard JavaScript Fetch Pattern (Runs immediately when the page loads)
const AUTH_URL = "https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/auth";

async function checkAuthSession() {
  try {
    // 1. Send GET request including the session cookie
    const res = await fetch(`${AUTH_URL}/me`, {
      method: "GET",
      credentials: "include" // MUST be 'include' to pass cookies across origins
    });

    if (res.ok) {
      const data = await res.json();
      console.log("User is currently logged in:", data.user);
      // Update UI: show dashboard, hide login form
      renderUserDashboard(data.user);
    } else {
      console.log("No active session or session expired.");
      // Update UI: show login/register buttons
      renderLoginForm();
    }
  } catch (err) {
    console.error("Auth check failed:", err);
    renderLoginForm();
  }
}

// Call on window load or DOMContentLoaded
window.addEventListener("DOMContentLoaded", checkAuthSession);
Important Implementation Notes:
  • Always specify credentials: "include": Modern browsers will not transmit cookies to cross-origin API endpoints unless this flag is explicitly set.
  • Session Expiry & Storage: Sessions are stored directly in your GitHub database under authentication/sessions/ and automatically expire after 30 days.
  • Logging Out: Calling POST /auth/logout with credentials: "include" clears the cookie from the browser and destroys the session file on the server.
User Profile
GET / PATCH / DELETE /auth/me

Session Profile Management

Reads and updates the currently authenticated user profile. The password hash is automatically stripped from the response payload.

Profile Operations (/auth/me)
const BASE_AUTH = "https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/auth";

// 1. Get Current User Profile (GET /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/auth/me)
const meRes = await fetch(`${BASE_AUTH}/me`, { credentials: "include" });
if (meRes.ok) {
  const { user } = await meRes.json();
  console.log("Logged in as:", user);
}

// 2. Update Profile Name (PATCH /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/auth/me)
await fetch(`${BASE_AUTH}/me`, {
  method: "PATCH",
  credentials: "include",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "Alice Wonderland" })
});

// 3. Delete Account Permanently (DELETE /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/auth/me)
await fetch(`${BASE_AUTH}/me`, { method: "DELETE", credentials: "include" });
Account Security
POST /auth/password | PATCH /auth/email

Changing Password & Email

Both operations require the user's existing password for verification. Changing email atomically releases the old HMAC email key and claims the new one.

Updating Password and Email
const BASE_AUTH = "https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/auth";

// 1. Change Password (POST /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/auth/password)
await fetch(`${BASE_AUTH}/password`, {
  method: "POST",
  credentials: "include",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    oldPassword: "OldPassword123!",
    newPassword: "NewStrongPassword456!"
  })
});

// 2. Change Email Address (PATCH /U6op8Nr462Z46tBgxa2COUnja5z1/app-db/auth/email)
await fetch(`${BASE_AUTH}/email`, {
  method: "PATCH",
  credentials: "include",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    newEmail: "new.email@example.com",
    password: "CurrentPassword123!"
  })
});
Password Recovery
POST /auth/forgot-password

Password Reset Workflow & Built-in Form

When a user submits their email, Breacher generates a 15-minute cryptographically signed token and automatically dispatches an HTML reset email using your configured Gmail SMTP credentials. The link opens a responsive reset page served natively by the worker.

Requesting a Password Reset
const res = await fetch("https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/auth/forgot-password", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ email: "user@example.com" })
});
const data = await res.json();
console.log(data.message);
OAuth 2.0
GET /auth/github/*

GitHub OAuth Sign-In

Enable users to log in or sign up with their GitHub account. The API exchanges the OAuth code, fetches their verified email, sets a session cookie, and triggers BREACHER_AUTH_COMPLETE sync events.

GitHub OAuth Client Flow
// 1. Fetch GitHub Authorization URL
const resUrl = await fetch("https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/auth/github/url");
const { url } = await resUrl.json();

// 2. Redirect user to GitHub consent screen
window.location.href = url;

// 3. In your callback handler after redirect with ?code=XYZ:
const code = new URLSearchParams(window.location.search).get('code');
const loginRes = await fetch("https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/auth/github/callback", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ code })
});
const { user, isNew } = await loginRes.json();
console.log(isNew ? "Signed up!" : "Logged in!", user);
Advanced Web Push Engine
POST /notify/*

Advanced Web Push & Deep Sync

Our push notification system implements a zero-infrastructure, payload-free architecture. Because standard browser push encryption (RFC 8291) is highly temperamental and hard-capped at 4KB, our worker uses push as a lightweight wake-up signal. When a push wakes up the background Service Worker, it fetches the full custom JSON payload directly from your database queue. This bypasses size limits entirely, guarantees cross-browser reliability, and enables next-generation native behaviors.

1. REST API Specification: POST /notify/send

The backend accepts any arbitrary JSON properties and stores them verbatim inside your GitHub queue. The properties below are standard visual handles, but you can send any nesting of keys.

FieldTypeRoleDescription
targetUserIdstringRequiredThe User ID of the target recipient, or "all" to broadcast to everyone.
titlestringOptionalThe visual header of the alert. Skip if trigger is silent.
bodystringOptionalThe descriptive body text of your visual alert.
iconstringOptionalURL of the square thumbnail (e.g., sender profile picture). Can also be a Base64 data URI string.
badgestringOptionalURL of a monochrome logo icon shown in the device status bar on Android.
imagestringOptionalURL of a large visual banner / hero graphic displayed inside the expanded notification.
silentbooleanOptionalIf set to true, tells the service worker to process data in the background without raising a visual alert.
vibratenumber[]OptionalVibration rhythm array (e.g., [200, 100, 200]) for haptic feedback.
customActionsarrayOptionalInteractive button configurations (e.g., [{action: 'accept', title: 'Accept'}]).
DEMO 1

Handling Heavy JSON Lists (Collapsing Chat Floods)

If your backend sends 10 chat messages while a user is offline, standard push triggers 10 noisy beeps. Using our payload-free engine, we fetch the complete list from /notify/latest in one go. Our Service Worker reads the entire queue and merges them into a single visual summary notification.

Service Worker Code: Heavy List Aggregator
// Code placed inside sw.js
self.addEventListener("push", (event) => {
  event.waitUntil(
    (async () => {
      const userId = "alice_user_99";
      const res = await fetch(`https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/notify/latest?userId=${userId}`);
      if (!res.ok) return;

      const data = await res.json(); // Array of all pending JSON notifications
      const messages = data.notifications || [];
      
      if (messages.length === 0) return;

      // If we have only 1 notification, show it directly
      if (messages.length === 1) {
        const msg = messages[0];
        return self.registration.showNotification(msg.title, { body: msg.body, icon: msg.icon });
      }

      // If we have a heavy list of multiple messages, collapse them beautifully!
      const totalCount = messages.length;
      const senders = Array.from(new Set(messages.map(m => m.senderName || "Someone"))).join(", ");
      
      await self.registration.showNotification(`${totalCount} New Unread Updates! 📩`, {
        body: `You have new updates from ${senders}. Tap to read them all.`,
        badge: "/icons/badge.png",
        icon: "/icons/chat-group.png",
        tag: "collapsed-chat-group", // Prevents multiple notification windows
        data: {
          deepLinkUrl: "/chat/inbox"
        }
      });
    })()
  );
});
DEMO 2

Custom Banners, Buttons, & Vibration Patterns

Learn how to utilize rich browser handles to create expanded hero banners, specific haptic vibrations, and actionable interactive buttons.

Send Rich Layout (Backend Request Body)
// POST /notify/send body
{
  "targetUserId": "alice_user_99",
  "title": "Deluxe Pizza Order Dispatched! 🍕",
  "body": "Your gourmet order is out for delivery. Estimated arrival: 12 minutes.",
  "icon": "https://yourdomain.com/avatar-delivery.png",
  "image": "https://yourdomain.com/hero-delivery-map.png", // Large expanded banner
  "badge": "https://yourdomain.com/logo-monochrome.png",  // Status bar badge icon
  "vibrate": [100, 50, 100, 50, 150], // Custom vibration pattern
  "customActions": [
    { "action": "track", "title": "Track Live Map" },
    { "action": "cancel", "title": "Cancel Order" }
  ],
  "deepLinkUrl": "/orders/live-tracker"
}
Service Worker Code: Rendering Rich Banners & Vibrations
// Code inside sw.js
self.addEventListener("push", (event) => {
  event.waitUntil(
    (async () => {
      const res = await fetch(`https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/notify/latest?userId=alice_user_99`);
      if (!res.ok) return;

      const data = await res.json();
      for (const msg of data.notifications) {
        await self.registration.showNotification(msg.title, {
          body: msg.body,
          icon: msg.icon,
          image: msg.image, // Renders the large banner
          badge: msg.badge, // Android status bar icon
          vibrate: msg.vibrate || [200, 100, 200], // Haptics
          actions: msg.customActions ? msg.customActions.map(act => ({
            action: act.action,
            title: act.title
          })) : []
        });
      }
    })()
  );
});
DEMO 3

Embedding Visual Assets Natively (Inline Base64 Data)

When you pass simple image URLs, they can fail to load if cellular network coverage is spotty. Because payload-free push triggers a standard HTTP fetch with no size limit, you can embed your visuals directly as Base64 strings. They render instantly and with 100% offline-ready reliability.

Dispatch Inline Image Assets (Backend POST)
// POST /notify/send body containing base64 images
{
  "targetUserId": "alice_user_99",
  "title": "New Avatar Generated! ✨",
  "body": "Your personalized user avatar is ready.",
  // Inline Base64 Data URL instead of standard web links:
  "icon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
}
DEMO 4 (ADVANCED)

Silent Sync with Active App Windows (Push-to-Sync)

Push signals do not require visual popups. Sending a silent trigger wakes up the Service Worker in the background. It saves the heavy payload data straight to your local databases, then broadcasts a signal to all open tabs. Your active React pages instantly update their component states in real-time with zero page reload or visible spin!

Service Worker Background Sync Code (sw.js)
// Listen to background push signals
self.addEventListener("push", (event) => {
  event.waitUntil(
    (async () => {
      const res = await fetch(`https://storage.breacher.name.ng/U6op8Nr462Z46tBgxa2COUnja5z1/my-app-db/notify/latest?userId=alice_user_99`);
      if (!res.ok) return;

      const data = await res.json();
      for (const msg of data.notifications) {
        if (msg.silent === true) {
          // A. Save heavy payloads directly to IndexedDB or local database
          await writeToIndexedDB(msg.syncCollection, msg.syncData);
          
          // B. Broadcast success to all active open tabs
          const clientsList = await clients.matchAll({ type: "window" });
          for (const client of clientsList) {
            client.postMessage({
              type: "SILENT_SYNC_COMPLETE",
              collection: msg.syncCollection,
              updatedData: msg.syncData
            });
          }
        }
      }
    })()
  );
});
Frontend Component Integration (Active Tab React Code)
import { useEffect, useState } from "react";

export default function NotesDashboard() {
  const [notes, setNotes] = useState([]);

  useEffect(() => {
    // 1. Listen for background broadcast signals from the Service Worker
    const handleBackgroundSync = (event) => {
      if (event.data?.type === "SILENT_SYNC_COMPLETE" && event.data?.collection === "notes") {
        console.log("Background synchronization complete! Syncing state...", event.data.updatedData);
        // 2. Instantly append synced data straight into state with zero visual latency or spinners!
        setNotes((prevNotes) => [event.data.updatedData, ...prevNotes]);
      }
    };

    navigator.serviceWorker.addEventListener("message", handleBackgroundSync);
    return () => navigator.serviceWorker.removeEventListener("message", handleBackgroundSync);
  }, []);

  return (
    <div className="p-4 bg-slate-50 border rounded-lg">
      <h3 className="font-bold text-sm">Offline-Ready Notes</h3>
      <ul className="mt-2 space-y-1 text-xs">
        {notes.map(n => <li key={n.id} className="p-2 bg-white border rounded shadow-xs">{n.text}</li>)}
      </ul>
    </div>
  );
}