This package provides a convenient interface to subscribe to browser/web push notifications using MagicBell.
If you're upgrading from v1, you might be interested in our migration guide.
Installation
Install the package using your package manager:
npm install @magicbell/webpush --save
Usage
WebPush Subscription methods are accessed through the WebPushClient
instance. The client is initialized using the user credentials in the form of the userExternalId
or userEmail
. Provide the userHmac
when your project has hmac-authentication enabled.
Alternatively, an JWT based authToken
can be used for authentication, but note that this for advanced use-cases only.
tsimport { WebPushClient } from '@magicbell/webpush';
const client = new WebPushClient({
apiKey: '024…0bd',
userEmail: 'person@example.com',
userHmac: 'NCI…I6M',
});
// obtain current subscription status
client.isSubscribed();
// subscribe to push notifications
client.subscribe();
// unsubscribe from push notifications
client.unsubscribe();
Options
apiKey String
Your MagicBell API key. You can find it in the MagicBell dashboard.
userEmail String
The email address of the user you want to authenticate. Required if no userExternalId
or authToken
is provided.
userExternalId String
The external ID of the user you want to authenticate. Required if no userEmail
or authToken
is provided.
userHmac String
The HMAC signature of the user you want to authenticate. Required if you want to use HMAC authentication. Not required when authenticating using the authToken
.
authToken String
The authentication token of the user, as alternative to using the userEmail
or userExternalId
. Note that in most cases, you should authenticate using userExternalId
or userEmail
.
Verify browser support
One of the first things you'd want to do, is to make sure that the user's browser supports service workers and push notifications. You can do so using the isSupported
utility. It returns true
if the browser supports push notifications, and false
otherwise.
tsimport { isSupported } from '@magicbell/webpush';
isSupported();
Service worker registration
The service worker is lazily obtained or registered when calling methods on the WebPushClient
. Providing the service worker script path to the client constructor allows us to register your service worker for you.
tsimport { WebPushClient } from '@magicbell/webpush';
const client = new WebPushClient({
// ...
serviceWorkerPath: '/sw.js',
});
If you wish to register the service worker using our utility, you can do so. It's a simple utility, that only registers the service worker if it's not already registered. Providing a small benefit over using navigator.serviceWorker.register
directly.
tsimport { registerServiceWorker } from '@magicbell/webpush';
registerServiceWorker('/sw.js');
For completeness, your service worker file should include:
tsimportScripts('https://assets.magicbell.io/web-push-notifications/sw.js');
Subscribe to push notifications
Subscribe the user to push notifications. This method will register a service worker if it isn't already registered. The service worker will be registered using the path provided in the serviceWorkerPath
option. If the service worker is already registered, it will be used to subscribe the user.
tsimport { WebPushClient } from '@magicbell/webpush';
const client = new WebPushClient({ ... });
await client.subscribe();
This call will:
- get the service worker registration
- unsubscribe from active push subscriptions
- open the browser dialog to enable push notifications
- create a new push subscription
- send the webpush token to our backend
Unsubscribe from push notifications
Unsubscribing and resubscribing is trivial, giving your users the option to "pause" push notifications.
tsimport { WebPushClient } from '@magicbell/webpush';
const client = new WebPushClient({ ... });
await client.unsubscribe();
This call will:
- get the service worker registration
- unsubscribe from active push subscriptions
- delete the webpush token on our backend
Get subscription status
Obtaining the subscription status is done using client.isSubscribed()
tsimport { WebPushClient } from '@magicbell/webpush';
const client = new WebPushClient({ ... });
const subscribed = await client.isSubscribed();
This call will:
- get the service worker registration
- get the active push subscription
- check if the webpush token is used by our backend
Subscribing via new browser window / popup
A popular pattern to subscribe to push notifications, is using a new browser window, on a different (sub)domain, so that notifications come from a different domain than the one your site is running on.
As the user email and hmac are sensitive data, you don't want to transfer them to the popup via the url, as it will then end up in the browser history, leaking sensitive data.
To support this flow, we offer a way to obtain an auth token, and use that short-lived token in a second client instance.
On your main page:
tsimport { WebPushClient } from '@magicbell/webpush';
const client = new WebPushClient({
apiKey: '024…0bd',
userEmail: 'person@example.com',
userHmac: 'NCI…I6M',
});
// get the auth token and open the new window
const url = new URL('https://example.com')
url.searchParams.set('auth-token', await client.getAuthToken());
window.open(url.toString());
And then inside that popup:
tsimport { WebPushClient } from '@magicbell/webpush';
const searchParams = new URLSearchParams(location.search);
const authToken = searchParams.get('auth-token');
const client = new WebPushClient({
apiKey: 'NCI…I6M',
authToken: authToken,
});
await client.subscribe();
Api Methods
The SDK also exports a couple convenient api methods around our integrations API for the web_push channel. For most use-cases, the functions above should be sufficient, but when you need that raw data, these methods are ready to be used.
All the examples below work with the following client instance:
tsimport { WebPushClient } from '@magicbell/webpush';
const client = new WebPushClient({
apiKey: '024…0bd',
userEmail: 'person@example.com',
userHmac: 'NCI…I6M',
});
startInstallation
The client.startInstallation()
method can be called to obtain the project public_key
(also known as 'application server key') and json based auth_token
, which can be used as user authentication.
tstype Installation = {
public_key: string;
auth_token: string;
};
await client.startInstallation(): Promise;
getToken
Use this method to get a specific token from our backend:
tstype Token = {
id: string;
created_at: string;
updated_at: string;
discarded_at: string | null;
endpoint?: string;
keys?: Record;
};
await client.getToken(id: string): Promise
getTokens
Use this method to get all webpush tokens for this user, from our backend:
tstype Token = {
id: string;
created_at: string;
updated_at: string;
discarded_at: string | null;
endpoint?: string;
keys?: Record;
};
await client.getTokens(): Promise>
createToken
Use this method to create a webpush token in our backend. Note: PushSubscriptionJSON
is a native web type, not exported from our packages.
tsinterface PushSubscriptionJSON {
endpoint?: string;
expirationTime?: EpochTimeStamp | null;
keys?: Record;
}
const registration = await navigator.serviceWorker.ready;
const activeSubscription = await registration?.pushManager?.getSubscription();
const token: PushSubscriptionJSON = activeSubscription.toJSON()
await client.createToken(token): Promise>
deleteToken
Use this method to delete a webpush token from our backend.
tsawait client.createToken(tokenId: string): Promise