Shopify Online Store themes use Sagepilot’s Shopify app embed and Theme App Extension instead of installing this npm add-on directly. Follow Shopify Web Push setup. Use this guide for websites and custom/headless storefronts whose application code and public assets you control.
What you will build
Prerequisites
- A Sagepilot workspace and an active Push Notifications channel.
- A stable customer ID from your website’s authenticated session. Do not generate a new ID on every login or page load.
- An HTTPS website. Browser-recognized loopback hosts such as
localhostcan be used for local development. - A backend route that can authenticate the current website customer and sign a short-lived proof.
- A supported browser. Check capability with
isWebPushSupported()instead of relying on a hard-coded browser list.
https://app.sagepilot.ai.
If the same customer also uses your mobile app, use the same canonical customer identity for the app and website. Sagepilot stores the mobile FCM/APNs token and browser Web Push subscription as separate endpoints under that customer.
1. Configure the Sagepilot channel
In Sagepilot, create or edit a Push Notifications channel:- Under General, turn on Web Push and keep the channel active.
- Under Web Push, add one VAPID public key, its matching private key and a contact email.
- Under SDK & delivery, generate an Identity signing secret. Copy it now; the saved secret cannot be retrieved later.
- Choose the anonymous-customer policy and notification image policy your product needs.
- Click Save Changes.
workspace_id:push_channel_id integration key if your application team does not manage the channel.
To generate a new VAPID pair when your organization does not already manage one, you can use the standard web-push utility:
2. Install the packages
Install the Push add-on. The Website Widget installation remains a separately loaded Sagepilot script when your site also uses chat.Deploy the service worker
Copy the worker shipped by the add-on into your framework’s public/static directory so it is served at this exact same-origin URL:public/:
postinstall script so package upgrades deploy the matching worker. Verify the production URL returns JavaScript without authentication or a redirect:
scripts/copy-sagepilot-push-worker.mjs:
/sagepilot-push/ scope. It does not replace an existing root PWA service worker. Do not manually register the Sagepilot worker or change its filename or scope.
3. Generate a customer identity proof on your backend
Next.js App Router example
Use the complete Next.js example for authentication, the proof route, browser initialization, consent, logout and failed-revocation retry.
jose:
requireAuthenticatedCustomer() to your framework. The route must derive customer.id from the authenticated server session, not from an untrusted customer ID in the request body.
The proof contract is:
You may use an existing Sagepilot
customer_id instead of client_customer_id when your backend already stores that UUID. Do not send both identities unless you intentionally validate that they refer to the same customer.
4. Identify the customer in the browser
Create the Push instance in browser code after your host application restores its authenticated session. For server-rendered frameworks, keep this code in a client-only module or component.connectSagepilotPush() after login and on a full page reload while the customer remains signed in. identify() never prompts for notification permission. It also repairs a previously granted subscription, completes browser subscription rotation and flushes retained observations.
sync() reports the current state:
5. Request permission from a clear customer action
Callsubscribe() from the click handler of an explicit button. Do not call it during page load, login or chat initialization.
{ marketingConsent: true } only when the button copy clearly tells the customer that they are opting into marketing notifications. For support-only notifications, call subscribe() without that option and persist the appropriate support preference separately.
Browser permission and marketing consent are independent:
- Browser permission allows this origin to display notifications.
- Sagepilot preferences determine which notification categories the customer permits.
- A channel must also be active and the endpoint must be eligible for the send.
6. Use chat and Push together
Chat and Push remain separate even when your website uses both. Identify them from the same host-authenticated customer:client_customer_id should equal the stable user_id used for chat. Generate sagepilotUserHash on your server with the Website Widget identity secret and return it with the authenticated customer. Never expose that secret or generate the hash in browser code. If Website Widget identity verification is disabled, omit user_hash. The Widget hash and Push proof are separate credentials; neither replaces the other.
7. Handle logout, opt-out and teardown
Use the method that matches the customer’s action:
Attempt and await
logout() before clearing the host session, but never abandon the website’s sign-out flow if Push was not connected or the Sagepilot API is temporarily unavailable. A failed logout() retains the add-on’s delete-only binding. The fallback above removes the local browser subscription immediately, and retryPendingSagepilotPushLogout() retries server revocation before another customer can be identified. Report both failures to your monitoring. After a successful Push logout, the customer must explicitly subscribe again on the next login because logout removed the browser subscription.
8. Deep links, images and analytics
Use a same-origin HTTPS deep link that your website can load. The worker restricts notification navigation to the website’s own origin. An external-origin destination falls back to the website origin. When a notification is sent, the worker records signed observations automatically:
For
destination_opened, instantiate and identify the Push add-on on the landing page. The worker places only an opaque click marker in the URL; the add-on removes it after capture. Signed event data never enters the URL.
The worker retains observations when no page is open. The next identified page uploads them automatically. During testing, you can wait for an immediate upload:
9. Test end to end
1
Verify the worker asset
Open
/sagepilot-push/sagepilot-push-worker.js on the deployed origin and confirm it returns 200 JavaScript without a login page or redirect.2
Identify a real test customer
Sign in through your website. Confirm
connectSagepilotPush() returns permission_required, not_subscribed or registered without opening a prompt.3
Subscribe explicitly
Click your notification opt-in button, allow the browser prompt and confirm the result is
registered with a non-null endpointId.4
Send through the real product flow
Create a test list or segment containing only this customer, then send a Journey or Campaign through the Push channel. The current channel Test Send form targets Android/FCM, so do not use it as the Web Push verification path.
5
Test browser states
Confirm notification behavior with the page focused, in the background and closed. Browser and operating-system settings can affect presentation.
6
Verify engagement
Click the notification, confirm the intended same-origin page opens, call
flush() during development and inspect received, opened and destination-opened metrics separately.7
Verify cross-platform fan-out
Register the same customer in your mobile app and browser, then run one controlled Journey or Campaign. Each eligible active endpoint should receive its platform notification.
8
Verify revocation
Call
unsubscribe() or logout(), send again and confirm the revoked web endpoint is no longer eligible.A UI result such as “queued” proves only that the send entered Sagepilot’s delivery pipeline. It does not prove provider acceptance, service-worker receipt, browser presentation or a customer click. Use the separate analytics stages to locate a failure.
Troubleshooting
For method signatures and error fields, see the Web SDK API reference.