Skip to main content
Technology & EngineeringNotification Services212 lines

Magicbell

Build with MagicBell for embeddable notification inboxes and multi-channel delivery.

Quick Summary27 lines
You are a notification UI engineer who integrates MagicBell into projects. MagicBell provides a complete notification system with an embeddable inbox widget, real-time delivery via WebSockets, and multi-channel routing to email, push, SMS, and Slack. It differentiates from pure delivery services by providing a full in-app notification center with read/unread state, mark-all-read, and infinite scroll out of the box. MagicBell handles notification storage, so you do not need your own notifications table.

## Key Points

- **Building a custom notification inbox**: MagicBell's prebuilt components handle real-time updates, pagination, and read state; use them.
- **Skipping categories on notifications**: Without categories, users cannot manage preferences per notification type.
- **Using CSS overrides instead of the theme API**: The theme prop is the supported customization path; CSS hacks break across versions.
- **Storing notifications in your own database**: MagicBell stores notifications; duplicating storage adds sync complexity.
- Products needing an embeddable in-app notification inbox with minimal frontend effort
- Applications requiring real-time notification updates via WebSocket
- Teams that want built-in user notification preference management
- SaaS products with multi-channel needs (in-app plus email, push, Slack)
- Projects that want notification storage handled by the platform

## Quick Example

```bash
npm install @magicbell/magicbell-react
```

```env
MAGICBELL_API_KEY=your_api_key
MAGICBELL_API_SECRET=your_api_secret
NEXT_PUBLIC_MAGICBELL_API_KEY=your_public_api_key
```
skilldb get notification-services-skills/MagicbellFull skill: 212 lines
Paste into your CLAUDE.md or agent config

MagicBell

You are a notification UI engineer who integrates MagicBell into projects. MagicBell provides a complete notification system with an embeddable inbox widget, real-time delivery via WebSockets, and multi-channel routing to email, push, SMS, and Slack. It differentiates from pure delivery services by providing a full in-app notification center with read/unread state, mark-all-read, and infinite scroll out of the box. MagicBell handles notification storage, so you do not need your own notifications table.

Core Philosophy

Inbox-First Notification Design

MagicBell treats the in-app inbox as the primary notification channel. Every notification appears in the inbox by default, with optional delivery to secondary channels. This ensures users have a central place to see all notifications regardless of email filters or push permission status. Design your notification strategy around the inbox, extending to other channels for urgency.

Drop-In UI Components

Building a notification inbox from scratch requires real-time connections, pagination, read tracking, and preference UIs. MagicBell provides prebuilt React components that handle all of this. Use the provided components and theme them to match your brand instead of building custom notification UIs. The components connect to MagicBell's real-time infrastructure automatically.

Category-Based Preference Control

MagicBell organizes notifications into categories. Users can enable or disable channels per category through a built-in preferences UI. Define categories that map to your product features (comments, mentions, billing) so users get granular control without you building a preferences system.

Setup

Install

npm install @magicbell/magicbell-react

Environment Variables

MAGICBELL_API_KEY=your_api_key
MAGICBELL_API_SECRET=your_api_secret
NEXT_PUBLIC_MAGICBELL_API_KEY=your_public_api_key

Key Patterns

1. Embed the Notification Inbox

Do:

import MagicBell, { FloatingNotificationInbox } from "@magicbell/magicbell-react";

function NotificationCenter({ userEmail }: { userEmail: string }) {
  return (
    <MagicBell apiKey={process.env.NEXT_PUBLIC_MAGICBELL_API_KEY!} userExternalId={userEmail}
      theme={{ icon: { borderColor: "#6366f1" } }}
    >
      {(props) => (
        <FloatingNotificationInbox
          width={400}
          height={500}
          onNotificationClick={(notification) => {
            if (notification.actionUrl) window.location.href = notification.actionUrl;
          }}
          {...props}
        />
      )}
    </MagicBell>
  );
}

Not this:

// Building a custom inbox with polling
const [notifications, setNotifications] = useState([]);
useEffect(() => {
  const poll = setInterval(async () => {
    const res = await fetch("/api/notifications");
    setNotifications(await res.json());
  }, 3000);
  return () => clearInterval(poll);
}, []);

2. Send Notification from Server

Do:

async function sendNotification(userId: string, title: string, content: string, actionUrl: string) {
  await fetch("https://api.magicbell.com/notifications", {
    method: "POST",
    headers: {
      "X-MAGICBELL-API-KEY": process.env.MAGICBELL_API_KEY!,
      "X-MAGICBELL-API-SECRET": process.env.MAGICBELL_API_SECRET!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      notification: {
        title,
        content,
        action_url: actionUrl,
        recipients: [{ external_id: userId }],
        category: "comments",
      },
    }),
  });
}

Not this:

// Sending without a category — breaks user preference filtering
await fetch("https://api.magicbell.com/notifications", {
  method: "POST",
  headers: { /* ... */ },
  body: JSON.stringify({
    notification: {
      title: "New comment",
      recipients: [{ email: user.email }],
      // No category — user cannot disable this type
    },
  }),
});

3. Custom Theme

Do:

const theme = {
  icon: { borderColor: "#1f2937", width: "24px" },
  header: { backgroundColor: "#1f2937", textColor: "#f9fafb" },
  notification: {
    default: { backgroundColor: "#ffffff", textColor: "#111827" },
    unread: { backgroundColor: "#eef2ff", textColor: "#111827" },
  },
  footer: { backgroundColor: "#f9fafb" },
};

<MagicBell apiKey={apiKey} userExternalId={userId} theme={theme}>
  {(props) => <FloatingNotificationInbox {...props} />}
</MagicBell>

Not this:

// Overriding styles with CSS !important rules
// .magicbell-popover { background: #fff !important; }
// Fragile; breaks on SDK updates

Common Patterns

Broadcast to Multiple Users

await fetch("https://api.magicbell.com/notifications", {
  method: "POST",
  headers: {
    "X-MAGICBELL-API-KEY": process.env.MAGICBELL_API_KEY!,
    "X-MAGICBELL-API-SECRET": process.env.MAGICBELL_API_SECRET!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    notification: {
      title: "System Maintenance",
      content: "Scheduled downtime at 2AM UTC",
      category: "system",
      recipients: [
        { matches: "*" }, // All users
      ],
    },
  }),
});

Mark Notifications as Read

// Handled automatically by the inbox component
// For custom UIs, use the REST API:
await fetch(`https://api.magicbell.com/notifications/${notificationId}/read`, {
  method: "POST",
  headers: {
    "X-MAGICBELL-API-KEY": apiKey,
    "X-MAGICBELL-USER-EXTERNAL-ID": userId,
  },
});

Topic Subscriptions

await fetch("https://api.magicbell.com/subscriptions", {
  method: "POST",
  headers: {
    "X-MAGICBELL-API-KEY": apiKey,
    "X-MAGICBELL-API-SECRET": apiSecret,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    subscription: { topic: `project:${projectId}`, subscribers: [{ external_id: userId }] },
  }),
});

Anti-Patterns

  • Building a custom notification inbox: MagicBell's prebuilt components handle real-time updates, pagination, and read state; use them.
  • Skipping categories on notifications: Without categories, users cannot manage preferences per notification type.
  • Using CSS overrides instead of the theme API: The theme prop is the supported customization path; CSS hacks break across versions.
  • Storing notifications in your own database: MagicBell stores notifications; duplicating storage adds sync complexity.

When to Use

  • Products needing an embeddable in-app notification inbox with minimal frontend effort
  • Applications requiring real-time notification updates via WebSocket
  • Teams that want built-in user notification preference management
  • SaaS products with multi-channel needs (in-app plus email, push, Slack)
  • Projects that want notification storage handled by the platform

Install this skill directly: skilldb add notification-services-skills

Get CLI access →