Web push with ccs-chat-notifications-client
The /push entry points of ccs-chat-notifications-client register a browser for web push, so a user is notified when your app is closed. They use only the browser’s service worker and Push API and talk only to the Chat API. For the task view, see Web push.
Install
Section titled “Install”Install the package as described on the package page. The push entry points need no peer dependency. The React hook needs react.
import { ChatPushClient } from '@central-code-station/ccs-chat-notifications-client/push';import { usePushRegistration } from '@central-code-station/ccs-chat-notifications-client/push/react';Service worker
Section titled “Service worker”Copy the template from the package into your static root as push-sw.js. Serve it from the root of your site as JavaScript.
cp node_modules/@central-code-station/ccs-chat-notifications-client/push-sw-template.js public/push-sw.jsOn push it shows a notification from { notification: { title, body }, data }. On notificationclick it closes the notification, focuses an open window of your app, or opens /. It does not navigate to the conversation. data carries tenant_id, application_id, conversation_id and message_id for a deep link you add yourself. See Push payloads. ChatPushClient registers the file for you, so you never call serviceWorker.register yourself.
Register and unregister
Section titled “Register and unregister”The first permission prompt needs a real user gesture, so call register() from a click handler.
import { ChatPushClient } from '@central-code-station/ccs-chat-notifications-client/push';import { context } from './fe-guide-context';
// Push devices belong to the tenant, so there is no applicationId.const push = new ChatPushClient({ chatApiUrl: context.chatApiUrl, tenantId: context.tenantId, getAccessToken: context.getAccessToken, // serviceWorkerUrl: '/push-sw.js', // the default});
const enable = document.querySelector<HTMLButtonElement>('#enable-notifications');const disable = document.querySelector<HTMLButtonElement>('#disable-notifications');
if (!push.isSupported()) enable?.remove(); // no service worker or Push API here
// The first permission prompt needs a real click. Do not call register() on page load.enable?.addEventListener('click', async () => { const result = await push.register(); // never rejects if (!result.success) console.warn('Web push is not available', result.error);});
disable?.addEventListener('click', () => void push.unregister());| Member | Description |
|---|---|
isSupported() |
Whether this browser supports web push at all. Check it before you show the button. |
register() |
Registers the service worker, fetches Chat’s public key, subscribes with the Push API and sends the subscription to Chat. Safe to call again. Never rejects. |
unregister() |
Unsubscribes this browser and removes it from Chat. Works even if register() did not run in this session. Never rejects. |
Both methods return { success, error? } and log failures to the console as [ChatPushClient]. register() calls the public key operation and Register a device. unregister() calls Unregister a device. Devices belong to the tenant, so there is no applicationId and one registration covers all its applications.
ChatPushClientOptions
Section titled “ChatPushClientOptions”| Field | Required | Description |
|---|---|---|
chatApiUrl |
yes | The Chat API base URL. |
tenantId |
yes | The tenant whose notifications this browser receives. |
getAccessToken |
yes | Returns the user’s Chat token, sync or async. Read again on every register() and unregister(). |
serviceWorkerUrl |
no | Path of the service worker you host. Default /push-sw.js. |
React hook
Section titled “React hook”usePushRegistration(options) takes the same options and returns { isSupported, status, register, unregister }. status is 'idle', 'registering', 'unregistering', 'registered' or 'error'.
import { usePushRegistration } from '@central-code-station/ccs-chat-notifications-client/push/react';import { context } from './fe-guide-context';
export function NotificationsToggle() { const { isSupported, status, register, unregister } = usePushRegistration({ chatApiUrl: context.chatApiUrl, tenantId: context.tenantId, getAccessToken: context.getAccessToken, });
if (!isSupported) return null; const busy = status === 'registering' || status === 'unregistering'; // status starts as 'idle' and only tracks calls made from this hook. return ( <button disabled={busy} onClick={() => (status === 'registered' ? unregister() : register())}> {status === 'registered' ? 'Turn off notifications' : 'Turn on notifications'} {status === 'error' ? ' (not available)' : ''} </button> );}What the package does not do
Section titled “What the package does not do”- It does not detect an existing subscription.
statusstarts at'idle'and tracks only calls made through the hook. - It does not register native mobile devices, and it does not run in React Native.
- It has no
/push/angularentry point. There is no reactive state to bridge into a Signal, only two async actions, so injectChatPushClientinto your own@Injectable()service. - It does not choose who is notified. Chat sends web push only to offline members. See Push notifications.