
Research
Security News
Lazarus Strikes npm Again with New Wave of Malicious Packages
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
@magicbell/react-headless
Advanced tools
This package contains React headless components and hooks to build a notification inbox for your site powered by MagicBell.
Components
Hooks
The MagicBellProvider
component is the main component for building a custom
notification inbox. It fetches configuration from
MagicBell and keeps the list of notifications updated
in real time.
This is a headless component, so you can safely wrap your entire app in this component.
import React from 'react';
import ReactDOM from 'react-dom';
import { MagicBellProvider } from '@magicbell/react-headless';
ReactDOM.render(
<MagicBellProvider apiKey={MAGICBELL_API_KEY} userEmail="john@example.com">
<App />
</MagicBellProvider>,
document.body,
);
These are all the properties accepted by this component.
Property | Type | Description |
---|---|---|
apiKey | string | The API key of your magicbell.io project |
userEmail | string | The email of the user you want to show notifications for |
userExternalId | string | The external ID of the user you want to show notifications for |
userKey | string | The HMAC for the user. It is recommended to enable HMAC authentication but not required |
children | React.ReactChildren | The children to be wrapped in aMagicBellContext.Provider |
stores | object[] | An optional object containing the definitions of the notification stores to create. |
By default, one store for notifications is automatically configured. However, you can split your notification inbox if you want to.
For example, to split your inbox in read and unread notifications define each store as shown below:
import React from 'react';
import ReactDOM from 'react-dom';
import { MagicBellProvider } from '@magicbell/react-headless';
ReactDOM.render(
<MagicBellProvider
apiKey={MAGICBELL_API_KEY}
userEmail="john@example.com"
stores=[{ id: 'read', defaultQueryParams: { read: true }}, { id: 'unread', defaultQueryParams: { read: false }}]>
<App />
</MagicBellProvider>,
document.body,
);
Each store needs an id
and the query params (defaultQueryParams
) used for
filtering notifications when you fetch them from the MagicBell API server.
Hook to get a store of notifications for the current authenticated user. Returns
a notification store
.
Use this hook in the component that will render a list of notifications.
import { useNotifications } from '@magicbell/react-headless';
function Notifications() {
const store = useNotifications();
return (
<ul>
{store.notifications.map((notification) => (
<li key={notification.id}>{notification.title}</li>
))}
</ul>
);
}
When you split your inbox, provide the id of your store, e.g.:
import { useNotifications } from '@magicbell/react-headless';
function Notifications() {
const store = useNotifications('unread');
return (
<ul>
{store.notifications.map((notification) => (
<li key={notification.id}>{notification.title}</li>
))}
</ul>
);
}
Keep in mind, that the unread store should have been defined previously (see splitting the inbox).
This hook is very similar to the useNotifications
hook. It will return a
notification store.
import { useBell } from '@magicbell/react-headless';
function NotificationsList() {
const { unreadCount, markAllAsSeen } = useBell();
return (
<button onClick={() => markAllAsSeen()}>
<span>{unreadCount}</span>
</button>
);
}
The unreadCount
will be updated in realtime when new notifications arrive.
The only difference between the useNotifications
hook and this one is the
implementation of the markAllAsSeen
function. This function will mark
notifications as seen in other tabs, but not the current. This can help users to
identify new notifications (based on a style you would implement, for example).
When you split the notification inbox, you will have to provide the id of the store you want to fetch notifications from:
import { useBell } from '@magicbell/react-headless';
function NotificationsList() {
const { unreadCount, markAllAsSeen } = useBell({ storeId: 'unread' });
return (
<button onClick={() => markAllAsSeen()}>
<span>{unreadCount}</span>
</button>
);
}
This is a hook to listen to events, including realtime ones (generated in other tabs). Use it to be notified when a realtime event happens, for example to play a sound when a new notification arrives (read more in our guides).
import { useMagicBellEvent } from '@magicbell/react-headless';
useMagicBellEvent('notifications.new', (notification) => {
// Do something like showing a push notification
});
This is a list of events you can listen to:
Event name | Description |
---|---|
* | Any event |
notifications.new | A new notification for the authenticated user was created |
notifications.read | A notification was marked as read |
notifications.read.all | All notifications were marked as read |
notifications.unread | A notification was marked as unread |
notifications.seen.all | All notifications were marked as seen |
notifications.delete | A notification was deleted |
disconnected | The websocket connection was dropped |
reconnected | The websocket connection was reestablished |
You can also limit the source of the events you want to listen to:
remote
, to listen to events generated in other tabs or the MagicBell server onlylocal
, to listen to events generated in the same tab onlyany
, to listen to all events regardless of where it was generatedIt is set to any
by default.
import { useMagicBellEvent } from '@magicbell/react-headless';
useMagicBellEvent('notifications.new', callbackFn, { source: 'remote' });
Use this hook in the component that renders a notification. It will return a Notification object with all the methods needed to mutate it.
import { useNotification } from '@magicbell/react-headless';
function Notification(rawNotification) {
const notification = useNotification();
const handleClick = () => {
if (notification.isRead) notification.markAsUnread();
else notification.markAsRead();
};
return (
<button onClick={handleClick}>
<p>{notification.title}</p>
<p>{notification.sentAt.format('DDD MM, YYYY')}</p>
</button>
);
}
Use this hook to fetch and update the notification preferences for the user.
import { useNotificationPreferences } from '@magicbell/react-headless';
function NotificationPreferences() {
const { fetch, categories } = useNotificationPreferences();
useEffect(() => {
fetch();
}, []);
return (
<ul>
{categories.map((category) => (
<li key={category.slug}>
<p>{category.label}</p>
<div>
{category.channels.map((channel) => (
<p key={channel.slug}>
{channel.label}: {channel.enabled}
</p>
))}
</div>
</li>
))}
</ul>
);
}
Some of the hooks described above return a notification store which implement this interface:
interface INotificationStore {
unseenCount: number;
unreadCount: number;
total: number;
perPage: number;
totalPages: number;
currentPage: number;
notifications: Notification[];
isEmpty: boolean;
hasNextPage: boolean;
fetch: (queryParams) => Promise;
fetchNextPage: (queryParams) => Promise;
markAllAsRead: () => Promise<boolean>;
markAllAsSeen: () => Promise<boolean>;
}
fetch
Fetch notifications from the magicbell server. The pagination data is also updated. The provided query parameters are included in the request to the server.
The response is appended to the current array of notifications, so it can be
used as the view model for an infinite scroll list. If you want to reset the
collection instead, pass the reset: true
option to this method:
notifications.fetch({ page: 2 }, { reset: true });
fetchNextPage
This method is simply wrapping the fetch
method, sending as a parameter the
next page of notifications. You can include query parameters to this method.
markAllAsRead
Makes a POST request to the read notifications API endpoint.
It also sets the unreadCount
of the store to 0 and the readAt
attribute of
all notifications to the current time.
markAllAsSeen
Makes a POST request to the seen notifications API endpoint.
It also sets the unseenCount
of the store to 0 and the seenAt
attribute of
all notifications to the current time.
FAQs
Hooks to build a notification inbox
The npm package @magicbell/react-headless receives a total of 10,122 weekly downloads. As such, @magicbell/react-headless popularity was classified as popular.
We found that @magicbell/react-headless demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
Security News
Socket CEO Feross Aboukhadijeh discusses the open web, open source security, and how Socket tackles software supply chain attacks on The Pair Program podcast.
Security News
Opengrep continues building momentum with the alpha release of its Playground tool, demonstrating the project's rapid evolution just two months after its initial launch.