Push
Web Push SDK
The browser-side WRNexusPush JavaScript SDK — prompt, subscribe, unsubscribe, read and write per-topic preferences, and heartbeat tracking, all namespaced under window.WRNexusPush.
The Web Push SDK is a small, dependency-free browser script loaded from
https://api.wrnexus.com/push/sdk.js. Unlike the
language SDKs (which wrap the HTTP API with an API key), this SDK
runs on your visitors’ pages and is authenticated only by your non-secret
site key — there is no API key in the browser. Everything is namespaced under
window.WRNexusPush.
See Install the snippet to add it to your site. This page documents the runtime API it exposes.
Loading
<script
src="https://api.wrnexus.com/push/sdk.js"
data-site-id="SITE_KEY"
defer
></script>
The SDK auto-initialises on load: it resolves config, registers the service worker, and (for an already-subscribed browser) refreshes the server record. It never prompts for permission on load.
API
window.WRNexusPush exposes:
| Member | Returns | Notes |
|---|---|---|
prompt(opts?) |
Promise<{ ok, permission, id, subscription }> |
User-gesture only. Requests permission, subscribes, and registers. Alias: subscribe(). |
subscribe(opts?) |
same as prompt |
Backward-compatible alias of prompt(). |
unsubscribe() |
Promise<{ ok }> |
Unsubscribes the browser and deactivates the server-side subscription. |
isSubscribed() |
Promise<boolean> |
True when the browser currently holds a subscription for this site. |
isSupported() |
boolean |
True when serviceWorker, PushManager, Notification, and fetch exist. |
getPermission() |
'granted' | 'denied' | 'default' |
The current Notification.permission. |
requestPermission() |
Promise<string> |
Low-level permission request. Prefer prompt(). |
setPreferences(topics) |
Promise<{ ok, preferences }> |
Set per-topic opt-in state. topics is a { name: boolean } map. |
getPreferences() |
Promise<{ ok, preferences }> |
Read the subscriber’s per-topic preferences. |
track(extraMeta?) |
Promise<{ ok }> |
Re-sync an existing subscription (heartbeat). No prompt. |
config() |
Promise<config> |
Resolve the site config (siteKey, vapidPublicKey, apiBase, domain, icon). |
siteKey |
string |
The site key read from data-site-id. |
version |
string |
SDK version. |
prompt(opts?) — opt in
The only call that shows the browser permission prompt. Must be invoked from a real user gesture (a click handler) or browsers will silently suppress it.
button.addEventListener('click', function () {
WRNexusPush.prompt({ metadata: { plan: 'pro', userId: 'u_123' } }).then(function (res) {
if (res.ok) {
// res.id → WRNexus subscription id
// res.subscription → the W3C PushSubscription
console.log('subscribed', res.id);
} else {
// res.permission → 'denied' | 'default'
console.log('not subscribed', res.permission);
}
});
});
opts.metadata is merged into the subscription’s stored metadata (alongside the
page metadata the SDK captures automatically — see below).
unsubscribe()
WRNexusPush.unsubscribe().then(function (res) {
console.log('unsubscribed', res.ok);
});
Unsubscribes the browser’s PushSubscription and calls
POST /api/push/subscriptions/unsubscribe
so the server-side row is deactivated. Idempotent.
Per-topic preferences
Topics let a subscriber opt out of a category of notifications without
unsubscribing entirely. A campaign tagged with a topic skips subscribers who
have opted out of it.
// Opt the subscriber out of "promotions" but keep "order-updates"
WRNexusPush.setPreferences({ promotions: false, 'order-updates': true });
// Read current state → [{ topic: 'promotions', optedIn: false }, …]
WRNexusPush.getPreferences().then(function (res) {
console.log(res.preferences);
});
Both require an active subscription; when none exists they resolve
{ ok: false, reason: 'not-subscribed' }.
track(extraMeta?) — heartbeat
Re-syncs an existing subscription so the server advances its lastSeenAt. The
SDK calls this automatically on load for already-subscribed browsers; call it
yourself to attach updated metadata. It never prompts and is a no-op for a
visitor who has not subscribed.
WRNexusPush.track({ page: 'checkout' });
Subscription metadata
On every subscribe / track, the SDK captures and stores:
| Field | Source |
|---|---|
url |
window.location.href |
referrer |
document.referrer |
lang |
navigator.language |
tz |
Intl.DateTimeFormat().resolvedOptions().timeZone |
ua |
navigator.userAgent |
Anything you pass as opts.metadata (to prompt) or extraMeta (to track) is
merged on top. Metadata is shallow-merged server-side, so a page-load
heartbeat never wipes preferences set by an earlier call.
Transport details
All writes use a CORS-simple POST (a text/plain body, no custom headers,
credentials: 'omit') so they reach the API from any origin without a CORS
preflight. The API echoes Access-Control-Allow-Origin: * on these public
surfaces so the SDK can read the JSON response. You never send cookies or an API
key from the browser — requests are tenant-scoped by your site key alone.
Next steps
- Install the snippet — the two-step setup.
- Service worker setup — host the required worker file.
- Push API reference — the endpoints this SDK calls.
- Troubleshooting — permission denied, scope errors, 410s.