A client-side JavaScript SDK for web push notifications supporting Chrome, Firefox, and Safari. Published to npm as web-push-notifications and distributed via CDN.
Install dependencies:
npm installStart the local dev server:
npm startRuns webpack-dev-server on https://localhost:8003 with the CDN build configuration.
npm run build # development build
npm run build:prod # production build (minified)
npm run release # production build + zip packagenpm run check:types # TypeScript type-check
npm run check:lint # ESLint
npm run lint:fix # auto-fix ESLint issues- Provides the Pushwoosh Web Push SDK for integrating browser push notifications into websites
- Handles push subscription management across Chrome, Firefox, and Safari (including legacy Safari APNs)
- Includes a Service Worker for receiving and displaying push notifications
- Ships UI widgets: subscription popup, subscription button, subscription prompt, and in-app inbox
- Communicates with the Pushwoosh backend API for device registration, event tracking, and inbox messages
- Published as:
- CDN:
https://cdn.pushwoosh.com/webpush/v3/pushwoosh-web-notifications.js - npm:
web-push-notifications - GitHub: Pushwoosh/web-push-notifications
- CDN:
<script src="//cdn.pushwoosh.com/webpush/v3/pushwoosh-web-notifications.js" async></script>
<script>
var Pushwoosh = Pushwoosh || [];
Pushwoosh.push(['init', {
apiToken: 'YOUR_DEVICE_API_TOKEN',
applicationCode: 'XXXXX-XXXXX',
defaultNotificationTitle: 'Pushwoosh',
autoSubscribe: true
}]);
</script>Web popups are configured as campaigns in the Pushwoosh dashboard and rendered by
a separate widget bundle. It loads by default; pass enable: false to opt out:
Pushwoosh.push(['init', {
applicationCode: 'XXXXX-XXXXX',
webPopups: {
// enable: false, // opt out entirely: the bundle is never loaded
// autoShow: false, // never show a popup automatically; see below
},
}]);At most one popup is on screen at any moment. When several campaigns match the same page, they are shown one after another — ordered by their configured delay, then by the order the server returned them — and the next one appears shortly after the current one is dismissed.
A campaign can be set to Only via WebSDK call in the dashboard, in which case it is never displayed automatically and it is up to the site to show it:
Pushwoosh.moduleRegistry.webPopups.show('POPUP_CODE');Requires WebSDK 3.63.0 or newer. Older bundles do not understand the campaign trigger setting and display such popups automatically.
show() ignores the display conditions — delay, page rules, device type,
visitor type and frequency capping — because an explicit call is an explicit
intent. The campaign's push permission status still applies, and so does a countdown
that has run out — for a popup campaign only, not for an Inline (EMBEDDED) block. It closes
the currently visible popup to make room, records the same statistics as an automatic
display, and resolves false (never rejects) when the code is unknown, the status does
not match, the content cannot be loaded, a content code opens a form (forms need a campaign
code), an Inline campaign finds no element or a popup's countdown has run out.
The full interface:
| Method | Description |
|---|---|
show(code): Promise<boolean> |
Show a popup now, ignoring all conditions but the push permission status and, for a popup campaign, an expired countdown. |
hide(code?): boolean |
Hide the visible popup, or only the given one. |
hideAll(): boolean |
Hide the visible popup and drop everything still pending on this page. |
isVisible(code?): boolean |
Whether any popup — or the given one — is on screen. |
getVisibleCode(): string | null |
Code of the popup on screen. |
getAvailableCodes(): string[] |
Every popup code the server returned. |
getState(): WebPopupsState |
Snapshot of the pipeline: visible / queued / waiting / available. |
autoShow: false in the init params is the site-wide equivalent of the
per-campaign setting: popups are still loaded, but the SDK never shows one by
itself.
Pushwoosh.moduleRegistry.webPopups appears once the widget bundle has loaded,
which happens asynchronously after init. Calls made after that point are safe
even if the popup list is still loading — they queue internally. To be sure the
object exists, wait for the web-popups-ready event:
Pushwoosh.addEventHandler('web-popups-ready', function () {
Pushwoosh.moduleRegistry.webPopups.show('POPUP_CODE');
});| Event | Payload |
|---|---|
web-popups-ready |
— |
show-web-popup |
{ code, trigger } — trigger is 'auto' or 'api' |
hide-web-popup |
{ code, reason } — reason is 'user', 'api' or 'preempted' |
change-permission |
{ permission } — 'granted', 'denied' or 'default'; once per change, from a dialog answer or the site settings |
- TypeScript, Webpack 5, Babel
- No runtime framework dependencies (vanilla JS/TS; widgets from
websdk-commonrender with preact) @pushwoosh/logger(internal)@pushwoosh/websdk-common(internal, source infrontend-monorepo/packages/websdk-common) — code shared by WebSDK and the Pushwoosh Control Panel: models and renderers of the inbox, subscription widget and web popups. The Control Panel uses it for previews and the popup editor canvas, so changes to how these widgets look or behave are made there, not in this repo