Skip to main content

Web Push (browser notifications)

Send notifications to your visitors' browsers — even when your site isn't open. JourneyLayer Web Push uses the standard Web Push Protocol (VAPID), so one setup covers Chrome, Edge, Firefox, and macOS Safari 16+.

Permission is never auto-requested

The SDK never prompts for notification permission on page load. The native browser prompt only appears when you call JourneyLayer.webPush.subscribe() (or requestPermission()) from a real user action — a button click or a soft prompt's "Allow". This is both a browser requirement and good UX.

Customer setup (6 steps)

1. Add the JourneyLayer hosted script

If you haven't already, install the Website SDK — see Install:

<script src="https://cdn.journeylayer.com/p/<PROJECT_PUBLIC_ID>/jl-script.js" async></script>

2. Add your site to Allowed domains

Web Push subscribe/unsubscribe calls are origin-checked just like events. Add every origin you serve from under Settings → SDK / Install → Allowed domains (apex + www + staging). See Allowed domains.

3. Configure VAPID keys

In the dashboard, open Settings → Channels → Web push → Browser & OS:

  • Click Generate keypair (the private key is stored encrypted server-side and never shown), then
  • Enable the browsers you support (Chrome/Edge, Firefox, Safari) and Save each. Set a VAPID subject (a mailto: or https: contact for the push service).

4. Upload jl-sw.js to your website root

A push service worker must be same-origin with your pages — browsers won't register one from track.yourdomain.com or our CDN. So host our default worker on your own domain:

  • Download jl-sw.js and upload it to your site root, reachable at https://yoursite.com/jl-sw.js.
  • If you host it at a different path, set that path in the browser card's Service worker path field (default /jl-sw.js).

The worker handles displaying the notification, opening the click‑through URL, and best‑effort delivery/click tracking.

The hosted SDK cannot supply the service worker

The JourneyLayer SDK is loaded cross-origin (from our CDN or your track. subdomain), so it cannot register the push service worker for you — browsers only allow a service worker to be registered from the same origin as the page. This is why jl-sw.js must be hosted on your website root. The <script> SDK and the same-origin jl-sw.js worker are two separate files and the script can't replace the worker.

5. Ask for permission from a button or soft prompt

Call subscribe() from a click — never on load:

<button id="enable-notifications">Enable notifications</button>
<script>
document.getElementById('enable-notifications').addEventListener('click', async () => {
const res = await JourneyLayer.webPush.subscribe();
if (res.ok) {
console.log('Subscribed to web push');
} else {
console.log('Not subscribed:', res.reason); // e.g. permission_denied, not_configured
}
});
</script>

6. Verify the subscription

In JourneyLayer → Profiles / Find People, the visitor's profile shows a Web Push Subscribed event in their activity. You can also send a test from Settings → Channels → Web push → Send test.

SDK reference

All methods are on JourneyLayer.webPush and are safe to call — they return a result object and never throw. If Web Push isn't configured for your project, subscribe() resolves with { ok: false, reason: 'not_configured' }.

MethodReturnsNotes
getPermissionStatus()'default' | 'granted' | 'denied' | 'unsupported'Synchronous.
requestPermission()Promise<NotificationPermission>Shows the native prompt. Call from a user gesture.
subscribe()Promise<{ ok, reason? }>Requests permission (if needed), registers the SW, subscribes, and registers with JourneyLayer.
unsubscribe()Promise<{ ok }>Unsubscribes locally and revokes server-side.
isSupported()booleanfalse on browsers without Push/Notification APIs.

Soft prompt

A soft prompt is an optional pre-permission message ("Get notified about…") shown before the native dialog, so a "no" doesn't permanently block you. Design it under Settings → Channels → Web push → Soft Prompt (title, message, allow/later text, delay). Show it yourself, then call subscribe() when the visitor clicks Allow.

Browser support (V1)

BrowserStatus
Chrome / Edge / Brave / Opera✅ Supported
Firefox✅ Supported
Safari (macOS 16+)✅ Supported. iOS requires the site be installed as a PWA (Add to Home Screen).
KaiOS⛔ Not supported in V1

Troubleshooting

  • subscribe() returns not_configured — generate VAPID keys and enable at least one browser in Settings → Channels → Web push.
  • permission_denied — the visitor blocked notifications; they must re-allow in browser site settings. You can't re-prompt programmatically.
  • sw_register_failedjl-sw.js isn't reachable at the configured path on your origin (must be same-origin, served over HTTPS). Open https://yoursite.com/jl-sw.js to confirm it loads.
  • Nothing arrives after a test send — confirm the subscription exists (profile shows Web Push Subscribed), the browser tab can be closed but the OS must allow notifications, and check the browser isn't in a focus/Do-Not-Disturb mode.
  • 403 on subscribe — your page origin isn't in Allowed domains.