Web Push Setup
This guide walks through configuring OneSignal web push notifications for your Shopify store using Vendo.
Prerequisites
- A Shopify store with the Vendo app installed
- A OneSignal account (free tier available)
Step 1: Create a OneSignal App
- Log in to OneSignal
- Click New App/Website
- Enter your app name (e.g., your store name)
- Select Web as the platform
- Choose Custom Code as the integration type
Important: You must pick Custom Code. The Typical Site option does not let you customise the service worker path, and Shopify will not allow OneSignal’s default root-path service worker to be served. Vendo routes the service worker through the Shopify App Proxy at
/apps/vendo/, which only the Custom Code flow supports. If you’ve already created the app under Typical Site, switch it to Custom Code (or recreate the app) before continuing.
Use a dedicated OneSignal app per Shopify store. Each OneSignal Web Push app is tied to a single Site URL. If you reuse the same App ID across stores (e.g. copy credentials from a sister store), the OneSignal SDK will silently refuse to initialise on every store except the one whose URL matches, with a console warning like Can only be used on: https://<other-store>.myshopify.com. Push subscription and email capture both stop working until you give each store its own OneSignal app. See Troubleshooting below.
Step 2: Configure Web Push Platform
In the OneSignal setup wizard:
- Site Name — Your store name
- Site URL — Your Shopify store URL (e.g.,
https://yourstore.myshopify.com) - Default Icon URL — Upload your store icon (recommended: 256x256 PNG)
Service Worker Configuration
This is critical for Shopify stores. Shopify does not allow serving files from the site root, so the service worker must use a custom path. In OneSignal, expand Advanced Push Settings and toggle on “Customize service worker paths and filenames”, then enter:
| Field | Value |
|---|---|
| Path to service worker files | /apps/vendo/ |
| Main service worker filename | OneSignalSDKWorker.js |
| Updater service worker filename | OneSignalSDKWorker.js |
| Service worker registration scope | /apps/vendo/ |
Vendo’s OneSignal Push Settings page in the Shopify app displays these exact values with click-to-copy — no need to retype them.
- Click Save to complete the web platform setup
Step 3: Get Your Credentials
From the OneSignal dashboard, navigate to Settings > Keys & IDs:
- App ID — Your OneSignal application ID
- REST API Key — Used for server-side event syncing (optional but recommended)
Step 4: Configure in Vendo
- In the Vendo Shopify app, navigate to Destinations > OneSignal
- Enter your OneSignal App ID
- Optionally enter your REST API Key for server-side events
- Click Save
Step 5: Enable the Theme Block
- In your Shopify admin, go to Online Store > Themes > Customize
- Click App embeds (in the left sidebar)
- Enable the Vendo theme block
- Save the theme
The Vendo theme block loads the OneSignal SDK on your storefront and handles:
- SDK initialization with your App ID
- Service worker registration at the correct path
- Push prompt display based on your settings
- User identification (push subscription, login, newsletter signup)
- Tag syncing for identified users
Step 6: Configure Push Prompts in the Vendo App
Important — clear your OneSignal dashboard prompts first.
OneSignal’s SDK combines dashboard-configured prompts with Vendo’s init options: Vendo can add prompts but cannot remove prompts you’ve configured in OneSignal. If you leave prompts in OneSignal’s Permission Prompt Setup, they’ll still render on your storefront regardless of Vendo admin toggles.
Before enabling any Vendo Push Setting, go to OneSignal dashboard → Web Push → Permission Prompt Setup and delete all prompts listed there. Vendo’s admin will then be the sole source of truth for what your storefront shows.
In the Vendo app, open OneSignal > Push Settings. You’ll see four sections, each with its own toggle:
| Section | What it does | When you’d use it |
|---|---|---|
| Subscription Bell | Floating bell icon visitors can click to subscribe | A persistent subscribe affordance — useful for always-visible opt-in |
| Push Slide Prompt | Branded slide-in banner asking for push permission | The default for most stores — less intrusive than the native dialog alone |
| Native Browser Prompt | Triggers the browser’s built-in permission dialog on a timer | If you want to skip the slide prompt and ask immediately. Fires OneSignal.Notifications.requestPermission() after your configured delay |
| Welcome Notification | Push notification sent automatically the moment a visitor subscribes | Confirms the subscription and sets expectations |
For Push Slide and Native, you set triggers — how many page views and how many seconds to wait before the prompt fires. Sensible defaults (1 page view, 10s for slide, 20s for native) are pre-filled.
For Welcome, you set the title and message shown in the push notification.
All four are off by default — enable only the ones you want. Save once at the bottom of the page; changes take effect on the next storefront load (no theme redeploy required).
How Vendo and OneSignal interact
Per OneSignal’s Web SDK reference , init options from the storefront can add prompts to what the dashboard already serves — they cannot subtract. Vendo uses only documented init keys (appId, safari_web_id, serviceWorkerPath, serviceWorkerParam, notifyButton, promptOptions, welcomeNotification) plus the documented OneSignal.Notifications.requestPermission() method for the native prompt.
Effect:
- Subscription Bell — fully controlled by Vendo (
notifyButton.enable). Dashboard bell config is ignored. - Push Slide — added when Vendo toggle is on; nothing sent when off. Any slidedown still configured in your OneSignal dashboard will render on top.
- Native Browser Prompt — Vendo calls
requestPermission()on a timer when enabled and Push Slide is off. Independent of OneSignal dashboard config. - Welcome Notification — Vendo passes
welcomeNotification.title/messagewhen enabled. When disabled in Vendo, OneSignal’s dashboard welcome (if set) still fires.
What still lives in OneSignal’s dashboard
Vendo’s admin controls prompt visibility and triggers. Everything downstream of the subscription — composing and sending the actual push notifications — stays in OneSignal:
- Default notification icon (Site Settings → Default Icon URL) — applied to every push OneSignal sends, set once per app
- Notification content & campaigns — compose messages, upload images, schedule sends
- Segments — audience targeting rules (by tag, subscription date, country, etc.)
- Automations / journeys — trigger-based sends (welcome series, cart abandon follow-ups, etc.)
- A/B testing of sent notifications — split test message variants on campaign send
- Analytics — delivery, click-through, opt-in funnels
Prompt-level copy (accept/cancel button labels, action message), category opt-ins, and prompt localisation are not currently supported — Vendo’s init passes the slide prompt with SDK defaults for text and only uses type: "push" prompts. If you need these, ping us and we’ll add them to Vendo admin.
From the Vendo app’s Push Settings, click Open OneSignal Dashboard — it deep-links to your app. Use it to compose campaigns and manage your audience, not to add prompts (those go in Vendo admin).
Step 7: Verify Setup
Check Service Worker
Visit your store and open browser DevTools (F12):
- Go to Application > Service Workers
- Verify
OneSignalSDKWorker.jsis registered - The scope should show
/apps/vendo/
Test Notifications
- Subscribe to push notifications on your store
- In the OneSignal dashboard, go to Messages > New Push
- Send a test notification to yourself
- Verify the notification appears
Verify in OneSignal Dashboard
- Go to Audience > All Users
- Confirm your test subscription appears
- Check that user tags are being synced (email, name, etc.)
Verify live settings with the console diagnostic
Push notification changes can take 1–2 minutes to reflect on your storefront — Shopify caches the shop metafield and OneSignal caches SDK config. If a setting you just saved doesn’t look right yet, wait a minute before investigating.
To confirm which push settings are actually live on your storefront (versus what you saved in Vendo admin), paste this script into the browser DevTools console on your storefront (F12 or Cmd+Option+I → Console tab → paste → Enter). It prints the current metafield, theme extension version, OneSignal dashboard state, and browser subscription state, plus a short verdict identifying the next action if something looks off.
(async () => {
const r = {};
const h = await (
await fetch(location.origin + "/?_d=" + Date.now())
).text();
const meta = h.match(/"onesignal":\{[^}]+\}/);
r.metafield = meta ? meta[0] : "MISSING";
r.hasNewInitCode = {
requestPermission: h.includes("OneSignal.Notifications.requestPermission"),
noEnabledFalseHack: !h.includes("enabled: false, autoPrompt: false"),
safariWiring: h.includes("os.safari_web_id"),
};
const appId = meta ? meta[0].match(/"app_id":"([^"]+)"/)?.[1] : null;
if (appId) {
try {
const cfg = await (
await fetch(
"https://onesignal.com/api/v1/sync/" + appId + "/web?t=" + Date.now()
)
).json();
r.onesignalDashboard = {
bellConfigured: "bell" in cfg.config.prompts,
nativeConfigured: "native" in cfg.config.prompts,
slidedownPromptCount:
cfg.config.prompts.slidedown?.prompts?.length || 0,
slidedownPromptTypes: (
cfg.config.prompts.slidedown?.prompts || []
).map((p) => ({
type: p.type,
autoPrompt: p.autoPrompt,
delay: p.delay,
})),
};
} catch (e) {
r.onesignalDashboard = "fetch failed: " + e.message;
}
}
const regs = await navigator.serviceWorker.getRegistrations();
r.browser = {
serviceWorkers: regs.map((g) => ({
scope: g.scope,
script: g.active?.scriptURL,
})),
notificationPermission: Notification.permission,
oneSignalPermission: window.OneSignal?.Notifications?.permission,
optedIn: window.OneSignal?.User?.PushSubscription?.optedIn,
onesignalId:
window.OneSignal?.User?.onesignalId ||
window.OneSignal?.User?.PushSubscription?.id,
nativePromptPageViews: parseInt(
localStorage.getItem("_vendo_onesignal_native_pv") || "0",
10
),
};
console.log("=== VENDO x ONESIGNAL DIAGNOSTIC ===");
console.log("1. METAFIELD:", r.metafield);
console.log("2. THEME EXTENSION VERSION (expect all true):", r.hasNewInitCode);
console.log(
"3. ONESIGNAL DASHBOARD (cleared if all false/0):",
r.onesignalDashboard
);
console.log("4. BROWSER STATE:", r.browser);
const v = [];
if (!r.hasNewInitCode.requestPermission) {
v.push("THEME EXTENSION IS OLD - redeploy needed");
} else {
v.push("Theme extension has latest init code");
}
if (
typeof r.onesignalDashboard === "object" &&
(
r.onesignalDashboard.bellConfigured ||
r.onesignalDashboard.nativeConfigured ||
r.onesignalDashboard.slidedownPromptCount > 0
)
) {
v.push("ONESIGNAL DASHBOARD still has prompts - clear Permission Prompt Setup");
} else if (typeof r.onesignalDashboard === "object") {
v.push("OneSignal dashboard is clean");
}
if (r.browser.notificationPermission === "denied") {
v.push("BROWSER permission DENIED - reset via lock icon");
} else if (r.browser.notificationPermission === "granted") {
v.push("Already subscribed - test in fresh incognito");
} else {
v.push("Browser permission is default (ready)");
}
console.log("5. VERDICT:");
v.forEach((x) => console.log(" - " + x));
})();What the verdict tells you:
- “THEME EXTENSION IS OLD” → contact Vendo support; the theme extension needs to be redeployed
- “ONESIGNAL DASHBOARD still has prompts” → go to OneSignal → Web Push → Permission Prompt Setup and delete the entries listed there. Vendo’s init options can only add prompts, not suppress dashboard ones (per OneSignal’s Web SDK reference )
- “BROWSER permission DENIED” → your test browser previously blocked notifications; click the lock icon in the URL bar → Site settings → Notifications → Ask
- “Already subscribed” → prompts won’t show again in this browser profile; test in a fresh incognito window
Quick check: which App ID is the storefront using?
After saving credentials in Vendo, the storefront page HTML inlines your OneSignal App ID. The fastest way to confirm a credential change has reached the storefront (vs. being stuck in Shopify’s page cache) is to paste this in the DevTools Console on any storefront page:
const m = document.documentElement.innerHTML.match(/"onesignal":\{[^}]*"app_id":"([^"]*)"/);
console.log("app_id rendered into page:", m?.[1] || "MISSING");If the printed App ID matches what you saved in the Vendo app, the metafield reached the storefront. If it shows an old value, you’re hitting Shopify’s page cache — see Storefront still shows old App ID below.
Troubleshooting
OneSignal init warning: “Can only be used on…”
In the storefront DevTools console, you see:
[Vendo] OneSignal init warning: Can only be used on: https://<some-other-store>.myshopify.comThe OneSignal app whose App ID is configured in Vendo has a Site URL set to a different store. OneSignal binds each Web Push app to a single origin and rejects initialisation from anywhere else.
This almost always happens when an App ID was copied from a sister store rather than creating a dedicated OneSignal app. It also catches a subtler case: if an app has multiple Site URLs configured, the OneSignal SDK (which loads its config via JSONP, no Origin header) gets back the primary/default Site URL — so even adding your new store URL as a secondary won’t fix it.
Fix — create a dedicated OneSignal app for this store:
- OneSignal → + New App/Website → Web Push → Site URL = your store’s
https://<store>.myshopify.com - Use Custom Code with the service worker paths from Step 2
- Copy the new App ID + REST API Key into the Vendo app’s OneSignal page and save
- Wait ~1–2 minutes for the Shopify storefront cache to refresh (or follow the next entry to force it)
Storefront still shows old App ID after changing credentials
You updated the OneSignal credentials in the Vendo app and verified the new App ID is in the metafield, but the storefront diagnostic still shows the old App ID and OneSignal init still warns about the old Site URL.
This is Shopify’s storefront page cache. The Vendo theme block renders the OneSignal config from the shop metafield directly into the page HTML — Shopify caches that rendered HTML at its edge, and the cached version sticks around even with ?cachebust= query strings.
Force a refresh — any one of these works:
- Re-save the page you’re testing on: Online Store → Pages → click the page → Save (no changes needed). Saving busts that page’s edge cache.
- Toggle the Vendo theme block: Online Store → Themes → Customize → App embeds → toggle Vendo off → Save → toggle on → Save. Invalidates every page.
- Wait: Shopify storefront cache typically refreshes within 1–10 minutes.
After the cache flushes, paste the Quick check snippet again — the App ID should match what’s in Vendo admin.
Settings changed in OneSignal dashboard haven’t taken effect
You changed Site URL, prompt config, or service worker paths in the OneSignal dashboard, but the storefront still behaves as if the old values were in place.
OneSignal caches its SDK config response (/sync/<app-id>/web) at the CDN for up to 1 hour. The OneSignal SDK loads this config via JSONP <script> tag (which doesn’t send an Origin header), and the response varies based on the request — so a curl with an Origin header may show fresh data while the browser sees stale data. Two layers can independently lag:
| Layer | Where it lives | Typical lag | How to bust |
|---|---|---|---|
| Shopify page cache | Shopify CDN | 1–10 min | Re-save the page or toggle the Vendo app embed |
| OneSignal /sync CDN | OneSignal’s CDN | Up to 1 hour | Wait. Pasting a unique App ID into Vendo (i.e. switching to a new OneSignal app) sidesteps it. |
If both layers look stuck after the lag windows above, run the diagnostic script and compare the four sections — any mismatch tells you which layer is stale.
Service Worker Returns 404
The service worker path must be /apps/vendo/OneSignalSDKWorker.js. Verify:
- The Vendo theme block is enabled in your Shopify theme
- You’re accessing the store via its primary domain
- In the OneSignal dashboard, Customize service worker paths and filenames is toggled on with the four values from Step 2 — if this section is collapsed or disabled, OneSignal falls back to the root path and Shopify will reject the request
”Typical Site” was selected during OneSignal setup
Vendo requires the Custom Code integration type. Typical Site does not expose the service-worker path settings, so the SDK will try to load /OneSignalSDKWorker.js from your store root — Shopify blocks that and push subscription will silently fail.
Fix: in the OneSignal dashboard, either switch the app’s integration type to Custom Code (Settings > Platforms > Web), or delete the app and recreate it with Custom Code from the start.
Push Prompt Not Appearing
- Check that the Vendo theme block is enabled in App embeds
- In the Vendo app under OneSignal > Push Settings, confirm at least one prompt toggle (Subscription Bell, Push Slide Prompt, or Native Browser Prompt) is turned on — all four default to off
- Check the trigger delay — a Push Slide set to e.g.
3 page viewswon’t fire on the first page load - Ensure your browser allows notifications (check browser settings)
- Verify you haven’t already dismissed or subscribed
- Try an incognito/private window
Notifications Show “Delivered” But Don’t Appear
- Check your OS notification settings (System Preferences > Notifications)
- Verify the browser has notification permissions
- Some browsers require the site to be served over HTTPS
Tags Not Appearing in OneSignal
- Tags sync only for identified users (logged in, subscribed to push, signed up for newsletter, or completed a purchase)
- Anonymous visitors are not tracked in OneSignal
- Check the Vendo app logs for sync errors
Events Not Triggering
- Verify the events are enabled in OneSignal > Events in the Vendo app
- Client-side events require the Web Pixel to be active and the user to be identified
- Server-side events require the REST API Key to be configured
- See How It Works for details on user identification