Use the Sendrealm React SDK to receive Web Push notifications in React, Vite, and Next.js apps.
This SDK runs in the browser and uses a Sendrealm app ID. It does not use a Sendrealm API key.
Never put a Sendrealm API key in browser JavaScript. Use @sendrealm/react for browser push registration and @sendrealm/sdk from trusted backend code to send notifications.
Requirements
- React 18 or newer.
- A Sendrealm Push App with the Web provider active.
- HTTPS in production.
- The Sendrealm service worker served from the same origin as your app.
- A notification permission prompt triggered from a user action.
iOS Web Push only works for installed Home Screen web apps with a valid web app manifest.
Install
npm install @sendrealm/react
Copy the service worker into your public root:
npx @sendrealm/react setup
Web Push service workers must be served from the same origin as the page. The default SDK path is /sendrealm-service-worker.js with scope /.
If you prefer to copy it manually:
cp node_modules/@sendrealm/react/sendrealm-service-worker.js public/sendrealm-service-worker.js
Initialize In React Or Vite
Call init() from browser code:
import { useEffect } from "react";
import { init, useSendrealmSubscription } from "@sendrealm/react";
const sendrealmAppId = "YOUR_SENDREALM_PUSH_APP_ID";
function NotificationButton() {
const { subscribed, optIn, optOut } = useSendrealmSubscription();
return (
<button onClick={() => (subscribed ? optOut() : optIn())}>
{subscribed ? "Disable notifications" : "Enable notifications"}
</button>
);
}
export function App() {
useEffect(() => {
void init({
appId: sendrealmAppId,
autoRequestPermission: false,
});
}, []);
return <NotificationButton />;
}
Initialize In Next.js
Put initialization in a Client Component:
"use client";
import { useEffect } from "react";
import { init } from "@sendrealm/react";
export function SendrealmInit() {
useEffect(() => {
void init({
appId: process.env.NEXT_PUBLIC_SENDREALM_PUSH_APP_ID!,
autoRequestPermission: false,
});
}, []);
return null;
}
Render <SendrealmInit /> once near your app shell, and put sendrealm-service-worker.js in public/.
Initialization Options
init({
appId: "YOUR_SENDREALM_PUSH_APP_ID",
environment: "production",
autoRequestPermission: false,
serviceWorkerPath: "/sendrealm-service-worker.js",
serviceWorkerScope: "/",
externalUserId: "user_123",
userEmail: "user@example.com",
});
| Option | Description |
|---|
appId | Sendrealm Push App ID from the dashboard. |
environment | Use development for test devices you want to target separately. Omit or use production for production. |
autoRequestPermission | Whether initialization asks for notification permission immediately. Most apps should keep this false. |
serviceWorkerPath | Same-origin URL for the service worker file. |
serviceWorkerScope | Service worker scope. Use / unless your app intentionally isolates push to a subpath. |
externalUserId | Optional user ID to link during initialization. You can also call login after sign-in. |
userEmail | Optional email to link during initialization. |
Service Worker Diagnostics
The SDK checks the configured service worker path before subscribing the browser.
Diagnostics include a serviceWorkerCheck object that reports common setup
issues such as missing files, HTML fallbacks, cross-origin worker URLs, or an old
worker file after an SDK upgrade.
const diagnostics = await getSendrealmClient().getDiagnostics();
console.log(diagnostics.serviceWorkerCheck);
Run the setup command again after package upgrades:
npx @sendrealm/react setup
You cannot register a GitHub or CDN URL directly as the Web Push service
worker. Browser service-worker registration requires the worker script to be
served from your application origin. You can use GitHub Releases as a download
source for the file, but deploy it into your app’s public directory.
Permission And Subscription UI
Browsers expect notification prompts to happen after a user action. Show your own explanation first, then call optIn() from a button click.
import { useSendrealmPermission, useSendrealmSubscription } from "@sendrealm/react";
export function PushSettings() {
const { permissionStatus, requestPermission } = useSendrealmPermission();
const { subscribed, optIn, optOut } = useSendrealmSubscription();
return (
<section>
<p>Permission: {permissionStatus}</p>
<p>Subscribed: {subscribed ? "yes" : "no"}</p>
<button onClick={() => void requestPermission()}>Ask permission</button>
<button onClick={() => void optIn()}>Enable notifications</button>
<button onClick={() => void optOut()}>Disable notifications</button>
</section>
);
}
Link A Signed-In User
import { getSendrealmClient } from "@sendrealm/react";
const sendrealm = getSendrealmClient();
await sendrealm.login("user_123", "user@example.com");
Call logout when the user signs out:
await sendrealm.logout();
Use tags for client-observed preferences, state, and behavior:
await sendrealm.addTags({
plan: "pro",
onboarding_complete: true,
locale: "en-US",
});
Track app events:
await sendrealm.trackEvent("checkout_started", {
cart_id: "cart_123",
total: 42,
});
Use backend-owned contact properties for authoritative account, billing, compliance, and verified profile data.
Notification Events
Use listeners when your app needs to react to notification opens or actions:
import { useEffect } from "react";
import { useSendrealm } from "@sendrealm/react";
export function NotificationEvents() {
const { client } = useSendrealm();
useEffect(() => {
const opened = client.addNotificationClickListener(event => {
console.log("opened", event.launchUrl, event.notificationId);
});
return () => opened.remove();
}, [client]);
return null;
}
Read the notification that opened the page:
const initialOpen = await getSendrealmClient().getInitialNotification();
Send To Web Devices
Once a browser is registered, send web push from trusted backend code with the JavaScript SDK:
await client.push.notifications.send({
app_id: "push_app_short_id",
external_ids: ["user_123"],
platforms: ["web"],
notification: {
title: "Hello from Sendrealm",
body: "This targets the user's registered web browsers.",
launch_url: "https://app.example.com",
},
});
Diagnostics
Use diagnostics to confirm browser support, device ID, permission status, subscription state, service worker path, and the latest SDK error.
const diagnostics = await getSendrealmClient().getSupportDiagnostics();
console.log(diagnostics);
Hooks
| Hook | Returns |
|---|
useSendrealm() | { client, state, initializing, error }. |
useSendrealmPermission() | { permissionStatus, permissionGranted, requestPermission }. |
useSendrealmSubscription() | { subscribed, token, optIn, optOut, refreshRegistrationToken }. |
Troubleshooting
| Symptom | What to check |
|---|
| Initialization runs during server rendering | Move init() to a Client Component or browser-only effect. |
| Permission prompt does not appear | Trigger opt-in from a user action and confirm the browser has not blocked notifications for the site. |
| Subscription fails | Use a full browser with push support and confirm the service worker file is served from the same origin. |
| Notifications do not open the expected URL | Confirm the notification has a launch URL and the browser allows the service worker to open it. |
| Images do not appear | Use HTTPS image URLs and expect browser support to vary. |
Related Pages