Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@magicbell/react-headless

Package Overview
Dependencies
Maintainers
2
Versions
78
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@magicbell/react-headless

Hooks to build a notification inbox

  • 4.4.7
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
8.3K
increased by3.24%
Maintainers
2
Weekly downloads
 
Created
Source

TypeScript code style: prettier minified minified + gzip npm version

React headless components for MagicBell

This package contains React headless components and hooks to build a notification inbox for your site powered by MagicBell.

  • Immutable
  • Full TypeScript support
  • Requires React 16.8+
  • Compatible with Preact

Table of Contents

MagicBellProvider

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.

PropertyTypeDescription
apiKeystringThe API key of your magicbell.io project
userEmailstringThe email of the user you want to show notifications for
userExternalIdstringThe external ID of the user you want to show notifications for
userKeystringThe HMAC for the user. It is recommended to enable HMAC authentication but not required
childrenReact.ReactChildrenThe children to be wrapped in aMagicBellContext.Provider
storesobject[]An optional object containing the definitions of the notification stores to create.

Splitting the inbox

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.

useNotifications

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).

useBell

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>
  );
}

useMagicBellEvent

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 nameDescription
*Any event
notifications.newA new notification for the authenticated user was created
notifications.readA notification was marked as read
notifications.read.allAll notifications were marked as read
notifications.unreadA notification was marked as unread
notifications.seen.allAll notifications were marked as seen
notifications.deleteA notification was deleted
disconnectedThe websocket connection was dropped
reconnectedThe 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 only
  • local, to listen to events generated in the same tab only
  • any, to listen to all events regardless of where it was generated

It is set to any by default.

import { useMagicBellEvent } from '@magicbell/react-headless';

useMagicBellEvent('notifications.new', callbackFn, { source: 'remote' });

useNotification

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>
  );
}

useNotificationPreferences

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>
  );
}

The notification store

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.

Keywords

FAQs

Package last updated on 21 Nov 2023

Did you know?

Socket

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.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc