Start typing to search the documentation.

to navigate·to open

Push

Push troubleshooting

Diagnose and fix common WRNexus Web Push problems — service worker scope errors, 410 subscription deactivation, denied permission, missing prompts, and silent notifications.

Common Web Push failure modes and how to resolve them. Turn on SDK logging with data-debug="true" on the snippet while debugging — it logs config resolution, worker registration, and subscription writes to the console.

Service worker scope error

Symptom. The console shows something like “The path of the provided scope (‘/’) is not under the max scope allowed”, or WRNexusPush.prompt() rejects because the worker never registers.

Cause. A service worker’s scope is limited to the directory it is served from. If you serve the worker from a sub-path (e.g. /assets/wrnexus-push-sw.js) but ask it to control /, the browser refuses.

Fix.

  • Best: serve the worker at the site roothttps://your-domain.example/wrnexus-push-sw.js — which gives it the default scope /.
  • If it must live at a sub-path: send the Service-Worker-Allowed: / header on the worker response and set data-sw-scope="/" on the snippet. Both are required. See Service worker setup.

Also confirm the worker is served with Content-Type: text/javascript, over HTTPS, and at the exact path the snippet’s data-sw points to (default /wrnexus-push-sw.js).

410 Gone — subscription deactivated

Symptom. A subscriber stops receiving notifications and shows as inactive in Push → Subscribers, with an unsubscribed event you did not trigger.

Cause. This is expected, healthy behaviour. When the push service reports a subscription as permanently gone — HTTP 404 or 410 — at send time (the user cleared site data, the browser rotated and discarded the subscription, or the push service expired it), WRNexus soft-deactivates that subscription so no future campaign wastes a send on it. The deactivation flips active = false, records an unsubscribed event, and updates the campaign’s send row.

Fix. Nothing is broken — this keeps your audience clean. To win the subscriber back, they simply re-subscribe (WRNexusPush.prompt()) the next time they visit. To survive routine browser key rotation without losing the subscriber, fill in the optional WRNEXUS_PUSH_CONFIG re-subscribe block in the worker — see Service worker setup.

Permission denied

Symptom. WRNexusPush.prompt() resolves { ok: false, permission: 'denied' } and no prompt appears.

Cause. The visitor (or a previous prompt) set notification permission to denied for your origin. Once denied, the browser will not show the prompt again — Notification.requestPermission() resolves immediately to denied. This is enforced by the browser, not WRNexus.

Fix.

  • You cannot re-prompt programmatically. The user must reset the permission via the site settings (the padlock/site-info icon in the address bar → Notifications → Allow / Reset).
  • Check the state first with WRNexusPush.getPermission() and show your own “notifications are blocked — here’s how to re-enable” hint when it returns 'denied', instead of calling prompt() into a no-op.

The prompt never appears (permission is default)

Symptom. Permission is default (not yet decided) but calling prompt() shows nothing.

Causes & fixes.

  • Not a user gesture. Browsers only show the prompt from a real user interaction. Call WRNexusPush.prompt() from inside a click handler — never on page load, in a setTimeout, or in a promise chain detached from the gesture.
  • Already subscribed. If the browser already holds a subscription, prompt() resolves { ok: true } without re-prompting. Check with WRNexusPush.isSubscribed().
  • Unsupported browser / insecure context. WRNexusPush.isSupported() returns false on browsers without the Push API, or when the page is not served over HTTPS (http://localhost is the only insecure exception).

config() fails — UNKNOWN_SITE or missing VAPID key

Symptom. Debug logs show “push config failed (404)” or “push site is not configured”.

Causes & fixes.

  • Wrong site key. data-site-id must be the exact publicKey from Push → Settings. A typo, a trailing space, or using a different site’s key all yield UNKNOWN_SITE (404).
  • Inactive site. A soft-deleted or non-active site returns UNKNOWN_SITE. Confirm the site’s status is active.
  • No active VAPID key. /push/config only returns when the site has an active VAPID key (provisioned automatically on site creation). If it is missing, re-create the site.

Notification arrives but is blank or has no icon

Symptom. The notification shows with a default title or no image.

Cause. The worker renders exactly what the campaign payload contains. Missing title/body/icon on the campaign produces a sparse notification (the worker falls back to the title "Notification").

Fix. Set title, body, iconUrl, and (optionally) imageUrl on the campaign. Icons and images must be HTTPS URLs the browser can fetch. The site’s iconUrl acts as a default when a campaign omits one.

Clicks open but no clicked event is recorded

Symptom. Notifications open the right page but Push → Analytics shows no clicks.

Causes & fixes.

  • Stale worker. You are running an old wrnexus-push-sw.js that opens data.url directly instead of the signed clickUrl. Re-copy the latest template from /push/sw.js.
  • Expired token. Tracking tokens are valid for one year. A click on a year-old notification hits /api/push/track/click/{token} and returns 410 Gone (the link is shown as expired) — expected for very old notifications.
  • Tracking is best-effort: an event is never double-counted (counters advance only on the first transition), so re-opening the same notification will not add a second click.

Subscriptions register but campaigns reach nobody

Checklist.

  • The subscriber is active (not deactivated by a 410 — see above).
  • The campaign’s siteId matches the site the subscribers belong to.
  • If the campaign has a topic, the subscriber has not opted out of it in their preferences.
  • The send is within the site’s frequency cap and outside its quiet hours — a capped or quiet-hours-suppressed send is skipped, not failed.

See also