SDK installation
ReachBell is one package per stack. You install a single package — and from it you can subscribe users to web push, identify them, tag them, and show in-page widgets. There's no separate client library to add and no API wiring for the common path; sending campaigns and building audiences happen in the dashboard.
| Your stack | Package | Wraps |
|---|---|---|
| Plain HTML / JavaScript | @reachbell/sdk (or a CDN <script>) | — (the core) |
| React | @reachbell/react | the core SDK |
| Vue 3 | @reachbell/vue | the core SDK |
| Next.js | @reachbell/nextjs | @reachbell/react |
| WordPress | ReachBell plugin | bundles the core SDK |
Pick the one path that matches your stack. The capabilities below are identical across all of them — only the ergonomics differ.
Vanilla JavaScript — @reachbell/sdk
The CDN <script> for plain HTML pages:
<script src="https://app.reachbell.com/reachbell.js" defer></script>
<script>
window.addEventListener("DOMContentLoaded", () => {
ReachBell.init({
apiKey: "rb_live_yourkey",
autoPrompt: true,
});
});
</script>Or the npm package for bundler-based projects:
npm install @reachbell/sdkimport { ReachBell } from "@reachbell/sdk";
ReachBell.init({
apiKey: "rb_live_yourkey",
autoPrompt: true,
});The bundle is ~15KB ESM, has zero runtime dependencies, and ships a dist/index.d.ts for TypeScript consumers. Either way you also need reachbell-sw.js served from the root of your domain — download it from the dashboard's integration page and place it next to your index.html. Service worker scope is bound to its served path, so it MUST be at the root or it can't control the whole site.
React — @reachbell/react
npm install @reachbell/react @reachbell/sdkimport { ReachBellProvider, useReachBell } from "@reachbell/react";
export default function App({ children }) {
return (
<ReachBellProvider apiKey="rb_live_yourkey" autoPrompt>
{children}
</ReachBellProvider>
);
}
function SubscribeButton() {
const { prompt, isReady, permission } = useReachBell();
if (!isReady) return <button disabled>Loading…</button>;
if (permission === "granted") return <span>You're subscribed</span>;
return <button onClick={() => prompt()}>Enable notifications</button>;
}The provider is StrictMode-safe and the underlying SDK ignores double-init by default. See the React guide for the full hooks reference.
Vue — @reachbell/vue
npm install @reachbell/vue @reachbell/sdk// main.ts
import { createApp } from "vue";
import { ReachBellPlugin } from "@reachbell/vue";
import App from "./App.vue";
createApp(App)
.use(ReachBellPlugin, { apiKey: "rb_live_yourkey", autoPrompt: true })
.mount("#app");Then, inside any component's setup():
<script setup lang="ts">
import { useReachBell } from "@reachbell/vue";
const { prompt, isReady, permission } = useReachBell();
</script>
<template>
<button v-if="permission !== 'granted'" :disabled="!isReady" @click="prompt">
Enable notifications
</button>
<span v-else>You're subscribed.</span>
</template>The plugin is SSR-safe. See the Vue guide for the composable reference. For a Vite project, place reachbell-sw.js in public/.
Next.js — @reachbell/nextjs
npm install @reachbell/nextjs @reachbell/react @reachbell/sdkIn the App Router, drop the provider in your root layout and mark the file "use client":
// app/providers.tsx
"use client";
import { ReachBellProvider } from "@reachbell/nextjs";
export function Providers({ children }) {
return (
<ReachBellProvider
apiKey={process.env.NEXT_PUBLIC_REACHBELL_KEY!}
autoPrompt
>
{children}
</ReachBellProvider>
);
}
// app/layout.tsx
import { Providers } from "./providers";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}For service worker scope, place reachbell-sw.js in public/ — Next serves the public/ directory from the site root, which is exactly where the SW needs to live. @reachbell/nextjs also ships a <ReachBellScript> CDN drop-in for pages that don't need a React-tree integration; see the Next.js guide.
WordPress
Install the ReachBell plugin from the WordPress.org plugin directory. From Settings → ReachBell, paste your API key. The plugin handles:
- Enqueuing the SDK (
assets/reachbell.jsbundled inside the plugin) on every front-end page. - Serving
reachbell-sw.jsfromhttps://yoursite.com/reachbell-sw.jsvia a rewrite rule, with the requiredService-Worker-Allowed: /header. - Optional auto-push on post publish (asynchronous — never blocks the editor).
See the WordPress guide for the full setup.
Identify and tag
Once the SDK is initialised, two client-side calls connect a browser subscription to your world. Both return a structured { ok, reason } rather than throwing.
Identify links the subscription to your internal user ID after login, so the dashboard can target by user instead of an opaque token:
const result = await ReachBell.identify("user_42");
if (!result.ok) console.warn("identify failed:", result.reason);Tag attaches flat string labels the dashboard's segment builder reads. Tags are additive — each call adds these labels to the device's existing tag set (to remove one, call POST /subscribers/untag):
await ReachBell.tag(["premium", "india"]);In React, Vue, and Next.js these are exposed on the useReachBell() hook/composable (identify, tag) so you don't touch the global object.
Identifying and tagging are how you make a subscriber addressable. You set the labels from the browser; you build the actual segments and send to them in the dashboard.
In-page widgets
The same package can render UI inside your page DOM — no notification permission required, because nothing leaves the browser. Useful for real-time alerts to users who are already on your site.
showToast(opts)— a stacking corner toast. Returns adismiss()function; auto-dismisses afterdurationms (default 5000).showBanner(opts)— a sticky top/bottom banner, one per position. Returnsdismiss().showNotificationCenter(opts)— a floating bell-icon button that opens a dropdown of recent notifications.
const dismissToast = ReachBell.showToast({
title: "Order shipped 📦",
body: "Order #4821 arrives tomorrow.",
url: "/orders/4821",
duration: 6000,
});
ReachBell.showBanner({
title: "🚀 Black Friday — 30% off everything",
body: "Code BLACK30 — ends midnight",
ctaText: "Shop now",
url: "/sale",
});
ReachBell.showNotificationCenter({ position: "bottom-right" });These widgets are client-side rendering only — they paint DOM in the current page. They are not push notifications and they don't send anything. To actually deliver a message to a user (in or out of your site), compose a campaign in the dashboard.
Tag outbound clicks
attachUtmTagger installs a single delegated click listener that appends UTM params to outbound (cross-origin) links, so your analytics attributes the session to ReachBell. Safe to call repeatedly.
ReachBell.attachUtmTagger({
source: "reachbell",
medium: "push",
campaign: "fall-2026",
});Same-origin links are left untouched, and any UTM param already on a URL wins. See the UTM tracking guide for conventions.
Verifying the install
After init runs, the SDK does the following:
GET /projects/contextwith your API key → fetches the prompt config and VAPID public key.navigator.serviceWorker.register('/reachbell-sw.js')→ installs the SW.- If
autoPrompt: true, arms a user-gesture listener that shows the soft prompt on the first interaction.
Check the browser DevTools' Application → Service Workers tab. A registered worker for reachbell-sw.js confirms steps 1 and 2 succeeded.
What's next?
- Run through the Quick start to ship a test push end-to-end.
- Read Concepts for the project / subscriber model the SDK maps to.
- Build audiences from your tags in the dashboard with Segments.
- Doing server-side transactional or mobile-native work? That's the secondary path — see Authentication in the Server API section.