Skip to content

Browser SDK reference

RelayBell.init() options (projectId, apiBase, swPath, swScope, externalId/userHash, tags, consent, autoCapture), window.relaybellInit and every SDK method.

JavaScript
RelayBell.init({
  projectId: "YOUR_PROJECT_ID",   // required
  apiBase:   "https://relaybell.com", // optional: defaults to where relaybell-sdk.js was loaded from
  swPath:    "/sw.js",            // service-worker path on your domain
  externalId: "user_123",         // link this browser to your own user id
  userHash: "9f2c…",              // your server's signature of externalId (see Identity verification)
  tags: { plan: "pro" },          // custom attributes for segmentation
  requireConsent: false,          // true = wait for grantConsent() (CMP integration)
  policyVersion: "2026-01",       // recorded with consent for your audit trail
  autoCapture: false              // true = record pageviews + data-rb-event clicks (see below)
});
OptionDescription
projectId *Your website's Project ID (dashboard: Install page, or Settings → Developers). Without it init() throws relaybell: projectId is required.
apiBaseThe relaybell address. Left out (or null), the origin relaybell-sdk.js was loaded from; "" means the page's own origin. A trailing / is removed.
swPathWhere your copy of sw.js is, on your own domain. Default "/sw.js". A full URL on another host (e.g. rewritten by a CDN plugin) is cut back to its path on the page's domain, since browsers only accept a same-origin service worker.
swScopeOptional scope for the service-worker registration, e.g. "/folder/" when sw.js isn't at the root. It is also how the SDK finds the registration again on later pages, so set it whenever sw.js lives in a folder. Left out, the browser's default (the folder sw.js is in).
externalId, userHashYour own user id for this visitor, and your server's signature of it (see Identity verification). Sent with the subscription and with every track() event.
tagsCustom attributes, { key: value }; values are stored as text. Used by segments (tag:KEY) and merge tags ({KEY}). Keys starting with rb_ are reserved and ignored.
requireConsent, policyVersionWith requireConsent: true the SDK registers no service worker, shows no opt-in prompt and sends no auto-captured events until you call grantConsent() (remembered in the browser's localStorage; revokeConsent() forgets it and unsubscribes). On-site messages still show. policyVersion is stored with the opt-in.
autoCapturetrue records page_view (including single-page-app route changes) and [data-rb-event] clicks; or pass { pageviews, clicks, scroll } to choose (scroll sends scroll_depth at 25/50/75/100%; it is off unless you turn it on). Only for subscribed or identified visitors, and nothing at all while requireConsent is waiting for consent. See Events.

init() returns a promise. Where push can't work it resolves { supported: false, needsInstall, reason } (needsInstall is true on an iPhone/iPad outside a Home Screen web app); while waiting for consent, { supported: true, waitingForConsent: true }.

Call init() once per page. A second call starts again from its own options. In React or Next.js, load the script with next/script (strategy="afterInteractive") and call RelayBell.init() in its onLoad inside a client component (or set window.relaybellInit, below), and put sw.js in Next's public/ folder so it is served at /sw.js. Step by step: Next.js, React, Vue and Nuxt.

Script loaded late? If your own code may run before relaybell-sdk.js has loaded (a delayed or consent-gated script), set the options on the page instead — the SDK starts itself with them once it loads (on the page's load event, or straight away if that has passed), unless init() already ran:

HTML
<script>window.relaybellInit = { projectId: "YOUR_PROJECT_ID", apiBase: "https://relaybell.com" };</script>
<script src="https://relaybell.com/relaybell-sdk.js" defer></script>

Methods

MethodWhat it does
init(opts)Registers the SW, shows the opt-in prompt, subscribes (see options).
subscribeNow()Triggers the browser permission prompt (call from a click). Resolves { supported, subscribed, permission?, reason? } — subscribed is true only once relaybell has stored the subscription; supported is false where the browser can't do push (e.g. iOS Safari in a normal tab). Safe to call before init() has finished: it waits up to ~15 s, then resolves with reason: "not_ready".
isSubscribed()Resolves true if this browser has a push subscription for your site. Never prompts — use it to decide whether to show a “Notify me” button or to track() interest.
identify(externalId, userHash)Links this browser to your own user id after the page has loaded (for example once the visitor signs in): an existing subscription is saved again with the id, and later track() events carry it. A browser with no id yet joins that user (a second device joins the same profile). A browser already linked to a different user moves to the new one only with a valid userHash (an account switch on a shared browser); without one it stays with the first user, so on a site without identity verification call unsubscribe() when someone signs out of a shared browser. Calling it again with the same values does nothing; identify(null) stops sending an id from this page. userHash is optional unless you require identity verification. Safe to call before init().
unsubscribe()Removes this browser's push subscription and tells relaybell, which records the opt-out (webhook subscriber.unsubscribed). Resolves { unsubscribed: true }.
isSupported(){ supported, browser, os, needsInstall, reason } — feature detection, no network call.
setTags({...})Merges the tags into the ones given to init() and, if this browser is subscribed, saves them (a key is overwritten, never removed). Resolves the merged tags.
setTopics(["news"])Saves the topics this subscriber wants, by slug. It replaces the whole list ([] leaves every topic); unknown slugs are skipped. Works only for a browser with a push subscription: resolves { ok: true, applied } (how many topics were saved), or { error: "subscriber_not_found" }.
showPreferences()Opens a preference-center modal of your topics, ticked with the subscriber's current choices; saving calls setTopics().
showInbox()Opens a modal of your 15 most recent broadcasts (never transactional, automation, journey or one-person sends).
track(event, props)Sends a behavioral event (fires automations, journeys and attribution). From the browser, the person is the subscriber who owns this browser's push subscription: an event from a browser that isn't subscribed is stored but triggers nothing for anyone. Its externalId is kept only when verified, or when verification isn't required and no userHash is sent.
trackConversion(value, props)Shorthand for track("purchase", { value, ...props }).
grantConsent() / revokeConsent()For cookie-consent (CMP) gating when requireConsent is set: grantConsent() starts the SDK as init() would have; revokeConsent() forgets the consent and calls unsubscribe().
JavaScript
// Behavioral tracking → powers cart abandonment, product alerts, attribution
RelayBell.track("cart.updated", { productId: "1234", product: "Blue Shoes", price: 49, url: location.href });
RelayBell.trackConversion(79.99, { orderId: "A123" });