Keep Reading
If you enjoyed the post you just read, we have more to say!
Last updated on
In-app notifications can be, and often are, very distracting. They’re triggered by website logins, abandoned carts, and feature updates. But certain notifications, like when someone needs your attention on a design file, are important and time-sensitive. These notifications need a place to live that’s not intrusive to your workflow.
A notification inbox can be the answer to those management problems. Building a solution in-house is an option, but we want you to be able to focus on building the core features of your product, not spending time building an inbox for all those important notifications.
We make notification customization easy with our MagicBell React SDK, React-headless component, and Browser JS library. (with support for English, Spanish, and Brazilian Portuguese)!
Good design and simplicity can go a long way when dealing with notifications. Notification customization begins with choosing a type of inbox to store notifications on your site or in your app.
MagicBell
is the root component in the SDK initializing a connection to magicbell.io. You can then implement the NotificationInbox
or the FloatingNotificationInbox
.
The NotificationInbox
is an infinite scroll list with an accompanying header and footer. This would be ideal to use if you wanted to build a separate page or section of your application for users to access notifications.
The FloatingNotificationInbox
is a tooltip render of the NotificationInbox
. This would be ideal to use if you wanted to build users an easy way to access their notifications from any page.
For this demo, we’ll be looking at the FloatingNotificationInbox
.
//Updates.tsx
<MagicBell
apiKey={MAGICBELL_API_KEY}
userEmail="john@example.com"
bellCounter="unread"
>
{(props) => (
<FloatingNotificationInbox
height={450}
NotificationItem={CustomNotification}
layout={["content", "header"]}
hideArrow
{...props}
/>
)}
</MagicBell>
This MagicBell
component first takes the API key and the user email, then allows for customization. In this example, we are using the bellCounter
to render the badge icon with the number of unread notifications. The icon
, header
, and footer
are being assigned custom values inside the custom theme object.
The FloatingNotificationInbox
is a tooltip component that renders notifications through the props. You can set the height and order the content within the component. In this example inside the layout, the content
is referencing the notifications, and the header
has been positioned below the notifications (as seen in the photo above).
The NotificationItem
is rendering a CustomNotification
component, which is customizing the props.
//CustomNotification.tsx
function CustomNotification({
notification
}: CustomNotificationProps) {
useNotificationWorkflow(notification);
const handleClick = () => {
if (!notification.isRead) notification.markAsRead();
else notification.markAsUnread();
};
return (
<div
className={`custom-notification ${notification.isSeen ? "seen" : "unseen"}`}
>
<UnreadState notification={notification} />
<div className="container" onClick={handleClick}>
<Sender notification={notification} />
<div>
<Title notification={notification} />
<Timestamp notification={notification} />
<Content notification={notification} />
<Actions notification={notification} />
</div>
</div>
</div>
);
}
A notification can have three notification customization states:
unread
unseen
onAllRead
In this example, the UnreadState
component is simply checking if the notification has been read, and if it has not been read, it renders a little blue SVG circle (as seen in the image above).
//UnreadState.tsx
function UnreadState({ notification }: { notification: Notification }) {
return (
<div className="unread-state">
{notification.isRead ? null : (
<svg viewBox="0 0 512 512">
<circle cx="256" cy="256" r="64" />
</svg>
)}
</div>
);
}
The other components being rendered in CustomNotification
are:
<Title notification={notification} />
<Timestamp notification={notification} />
<Content notification={notification} />
<Actions notification={notification} />
These render the notification data from MagicBell and display it in the tooltip.
You can play around with the React SDK demo here.
If you want more control with the advantage of hooks already built, you can get started with the React-headless component, which fetches and shows MagicBell notifications. Since this is a headless component, you can wrap your entire app in the MagicBellProvider
. In this example, we’ve built a quick solution for React Native.
The MagicBellProvider
initializes a MagicBellContext
, which keeps notifications updated in real time. There are three hooks to help you out.
First, useBell
is a hook that gets the number of unseen or unread notifications from the current user's last visit.
function Bell({ color }) {
const { badgeCounter } = useBell({counter: "unread"});
}
Second, useMagicBellEvent
is a hook for real-time events:
useMagicBellEvent('notifications.new', (notification) =>
{// Do something like showing a push notification});
You can use this hook to listen to:
notifications.new
notifications.read
notifications.read.all
notifications.unread
notifications.seen.all
notifications.delete
Third, useNotifications
is a hook for getting notifications from the current authenticated user:
//NotificationInbox.js
import { FlatList } from "react-native";
function NotificationInbox() {
const store = useNotifications();
if (!store) return null;
return (
<FlatList
data={store.items}
keyExtractor={(notification) => notification.id}
renderItem={({ item }) => <Notification notification={item} />}
/>
);
}
The headless component has support for multiple notification stores. This means it’s possible to have separate stores for unread
and read
by defining each one with a separate id
and context
.
<MagicBellProvider
apiKey={MAGICBELL_API_KEY}
userEmail="john@example.com"
stores=[
{id: 'read', context: { read: true }},
{ id: 'unread', context: { read: false }}]
>
<App />
</MagicBellProvider>
The NotificationStore
is a class that implements an interface with attributes, read-only properties, and methods. All the attributes are MobX observables. You can import the class from @magicbell/react-headless
, but if you’d like to avoid creating a new instance in your app, you can also load it through MagicBellContext
.
You can play around with the React-headless demo here.
If you need a quick implementation in the browser with vanilla JavaScript, we’ve got you covered with the MagicBell Browser JS library. Before your closing body tag, you can paste the following code snippet in (remembering to update the email and API key):
<div id="notifications-inbox" />
<script type="text/javascript">
(function(i,s,o,g,r,a,m) {i['MagicBellObject'] = r;(i[r] =i[r] ||function() {
(i[r].q = i[r].q || []).push(arguments);}),(i[r].l = 1 * new Date());(a = s.createElement(o)), (
m = s.getElementsByTagName(o)[0]);a.async = 1;a.src = g;m.parentNode.insertBefore(a, m);
})(window,document,'script','https://assets.magicbell.io/magicbell.min.js','magicbell');
var targetEl = document.getElementById('notifications-inbox');
var options = {
apiKey: MAGICBELL_API_KEY,
userEmail: CURRENT_USER_EMAIL,
height: 500,
};
magicbell('render', targetEl, options);
</script>
With this solution in place, you can identify users with either their email via userEmail
or by including the external_id
parameter with the notification in the API and calling userExternalId
in the front end.
A default theme is provided, meaning this solution can have you up and running with a working notification inbox quickly. If you want more notification customization and need to tailor the inbox to be on brand, you have that option with this solution as well.
You can customize the theme in the following ways:
The stylesheets
key allows you to use custom fonts:
theme: {
header: { fontFamily: 'IBM Plex Sans' }
notification: {
default: { fontFamily: 'IBM Plex Sans' },
unseen: { fontFamily: 'IBM Plex Sans' },
unread: { fontFamily: 'IBM Plex Sans' },
},
},
stylesheets: [
'https://fonts.gstatic.com',
'https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@200;500',
],
There’s also the ability to add your own custom hook when new notifications arrive. This would give you the ability to notify users in a custom way that they’ve received a new notification, like showing a toast or playing a sound.
In addition to our demos on CodeSandbox, we have example stories of our components in Storybook. Check out the code behind the components to get a better idea of what kind of notification customization is possible.
If your application or website can benefit from a notification inbox, get started with MagicBell by requesting an API key (no waiting), and start playing around!