Skip to main content

Integration Examples

Real-world examples of integrating NotificationControl into different applications.

Next.js App Router

// app/components/Header.tsx
'use client';

import NotificationControl from '@/components/notifications-control';
import { Bell } from 'lucide-react';
import { useRouter } from 'next/navigation';

export default function Header() {
  const router = useRouter();

  const BellIcon = ({ unreadCount }: { unreadCount: number }) => (
    <button className="relative p-2 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-full">
      <Bell className="w-6 h-6" />
      {unreadCount > 0 && (
        <span className="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full w-5 h-5 flex items-center justify-center">
          {unreadCount}
        </span>
      )}
    </button>
  );

  return (
    <header className="border-b">
      <nav className="container mx-auto px-4 py-3 flex justify-between items-center">
        <h1>My App</h1>

        <NotificationControl
          triggerComponent={BellIcon}
          onNotificationClick={(notif) => {
            router.push(`/notifications/${notif.id}`);
          }}
          onViewAllNotifications={() => router.push('/notifications')}
        />
      </nav>
    </header>
  );
}

React Router (SPA)

// components/Navigation.tsx
import NotificationControl from './components/notifications-control';
import { Bell } from 'lucide-react';
import { useNavigate } from 'react-router-dom';

export default function Navigation() {
  const navigate = useNavigate();

  const handleNotificationClick = (notification: any) => {
    // Navigate based on notification type
    switch (notification.type) {
      case 'comment-reply':
        navigate(`/posts/${notification.metadata.entityId}#comment-${notification.metadata.commentId}`);
        break;
      case 'entity-mention':
        navigate(`/entities/${notification.metadata.entityId}`);
        break;
      case 'new-follow':
        navigate(`/profile/${notification.metadata.followerId}`);
        break;
      default:
        navigate('/notifications');
    }
  };

  const BellIcon = ({ unreadCount }: { unreadCount: number }) => (
    <button className="relative">
      <Bell className="w-6 h-6" />
      {unreadCount > 0 && <span className="badge">{unreadCount}</span>}
    </button>
  );

  return (
    <nav>
      <NotificationControl
        triggerComponent={BellIcon}
        onNotificationClick={handleNotificationClick}
        onViewAllNotifications={() => navigate('/notifications')}
      />
    </nav>
  );
}

Social Media App

Filter notifications by category:
import NotificationControl from './components/notifications-control';
import { Bell } from 'lucide-react';

function SocialHeader() {
  return (
    <header>
      <NotificationControl
        triggerComponent={BellWithBadge}
        notificationTemplates={{
          'comment-reply': true,
          'comment-mention': true,
          'entity-upvote': true,
          'new-follow': true,
          'connection-accepted': true,
        }}
        onNotificationClick={(notif) => {
          if (notif.type === 'new-follow') {
            navigate(`/profile/${notif.metadata.followerId}`);
          } else if (notif.type === 'comment-reply') {
            navigate(`/post/${notif.metadata.entityId}`);
          }
        }}
      />
    </header>
  );
}

SaaS Dashboard

System notifications only:
import NotificationControl from './components/notifications-control';
import { Bell } from 'lucide-react';

function DashboardHeader() {
  return (
    <header>
      <NotificationControl
        triggerComponent={SystemBell}
        notificationTemplates={{
          'system': true,  // Only system notifications
        }}
        onNotificationClick={(notif) => {
          if (notif.metadata.buttonData) {
            window.location.href = notif.metadata.buttonData.url;
          }
        }}
      />
    </header>
  );
}

Mobile-Friendly Implementation

Responsive bell with proper mobile styling:
const MobileFriendlyBell = ({ unreadCount }: { unreadCount: number }) => (
  <button
    className="relative p-3 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-full transition-colors"
    aria-label={`Notifications${unreadCount > 0 ? `, ${unreadCount} unread` : ''}`}
  >
    <Bell className="w-6 h-6 md:w-5 md:h-5" />
    {unreadCount > 0 && (
      <span className="absolute top-1 right-1 bg-red-500 text-white text-xs font-bold rounded-full w-5 h-5 flex items-center justify-center">
        {unreadCount > 9 ? '9+' : unreadCount}
      </span>
    )}
  </button>
);

<NotificationControl
  triggerComponent={MobileFriendlyBell}
  onNotificationClick={handleClick}
/>

With Theme Toggle

Sync with app theme:
import { useState, useEffect } from 'react';
import NotificationControl from './components/notifications-control';
import { Bell, Moon, Sun } from 'lucide-react';

function Header() {
  const [isDark, setIsDark] = useState(false);

  useEffect(() => {
    // Sync with system theme on mount
    setIsDark(window.matchMedia('(prefers-color-scheme: dark)').matches);
  }, []);

  return (
    <header className={isDark ? 'dark' : ''}>
      <nav>
        <button onClick={() => setIsDark(!isDark)}>
          {isDark ? <Sun /> : <Moon />}
        </button>

        <NotificationControl
          triggerComponent={BellIcon}
          onNotificationClick={handleClick}
          theme={isDark ? 'dark' : 'light'}  // Styled variant only
        />
      </nav>
    </header>
  );
}

Community Platform

Filter for community interactions:
<NotificationControl
  triggerComponent={BellIcon}
  notificationTemplates={{
    'comment-mention': true,
    'comment-reply': true,
    'entity-upvote': true,
    'entity-comment': true,
  }}
  onNotificationClick={(notif) => {
    // Deep link to specific content
    if (notif.metadata.commentId) {
      navigate(`/posts/${notif.metadata.entityId}#comment-${notif.metadata.commentId}`);
    } else if (notif.metadata.entityId) {
      navigate(`/posts/${notif.metadata.entityId}`);
    }
  }}
  onViewAllNotifications={() => navigate('/inbox')}
/>

With Analytics Tracking

Track notification interactions:
import { analytics } from '@/lib/analytics';

<NotificationControl
  triggerComponent={BellIcon}
  onNotificationClick={(notif) => {
    // Track click event
    analytics.track('Notification Clicked', {
      notificationId: notif.id,
      notificationType: notif.type,
      isRead: notif.isRead,
    });

    // Handle navigation
    handleNavigation(notif);
  }}
/>

Accessible Implementation

Full accessibility with ARIA labels:
const AccessibleBell = ({ unreadCount }: { unreadCount: number }) => {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <button
      aria-label={`Notifications${unreadCount > 0 ? `, ${unreadCount} unread` : ''}`}
      aria-expanded={isOpen}
      aria-haspopup="true"
      onClick={() => setIsOpen(!isOpen)}
      className="relative"
    >
      <Bell className="w-6 h-6" />
      {unreadCount > 0 && (
        <span
          aria-label={`${unreadCount} unread notifications`}
          className="badge"
        >
          {unreadCount}
        </span>
      )}
    </button>
  );
};

Complete Working Example

Full implementation with all features:
'use client';

import { useState } from 'react';
import { ReplykeProvider } from '@replyke/react-js';
import NotificationControl from './components/notifications-control';
import { Bell } from 'lucide-react';

export default function App() {
  const [isDark, setIsDark] = useState(false);

  const BellTrigger = ({ unreadCount }: { unreadCount: number }) => (
    <button className="relative p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-800">
      <Bell className="w-6 h-6" />
      {unreadCount > 0 && (
        <span className="absolute -top-1 -right-1 bg-red-500 text-white text-xs w-5 h-5 rounded-full flex items-center justify-center">
          {unreadCount}
        </span>
      )}
    </button>
  );

  return (
    <ReplykeProvider projectId={process.env.NEXT_PUBLIC_REPLYKE_KEY}>
      <div className={isDark ? 'dark' : ''}>
        <header className="bg-white dark:bg-gray-900 border-b border-gray-200 dark:border-gray-700">
          <nav className="container mx-auto px-4 py-3 flex items-center justify-between">
            <h1>My App</h1>

            <div className="flex items-center gap-4">
              <button onClick={() => setIsDark(!isDark)}>
                {isDark ? '☀️' : '🌙'}
              </button>

              <NotificationControl
                triggerComponent={BellTrigger}
                onNotificationClick={(notification) => {
                  console.log('Notification clicked:', notification);
                  // Handle navigation
                }}
                onViewAllNotifications={() => {
                  window.location.href = '/notifications';
                }}
              />
            </div>
          </nav>
        </header>

        <main>
          {/* Your app content */}
        </main>
      </div>
    </ReplykeProvider>
  );
}

Next Steps