Loading...
Loading...
> Build real-time features like notifications, presence tracking, and activity feeds using Pusher Channels.
Fabrk integrates Pusher Channels to provide real-time communication between your server and clients. This enables instant updates for notifications, live activity feeds, and presence tracking to show who's online in your organization.
DESC: Add your Pusher credentials to your environment variables
1$# .env.local2$PUSHER_APP_ID=your_app_id3$PUSHER_KEY=your_key4$PUSHER_SECRET=your_secret5$PUSHER_CLUSTER=your_cluster67$# Client-side (exposed to browser)8$NEXT_PUBLIC_PUSHER_KEY=your_key9$NEXT_PUBLIC_PUSHER_CLUSTER=your_cluster
Use the server client to trigger events from your API routes
1// src/lib/pusher/server.ts2import Pusher from "pusher";34export const pusherServer = new Pusher({5 appId: process.env.PUSHER_APP_ID!,6 key: process.env.PUSHER_KEY!,7 secret: process.env.PUSHER_SECRET!,8 cluster: process.env.PUSHER_CLUSTER!,9 useTLS: true,10});1112// Trigger a notification13await pusherServer.trigger(14 `user-${userId}`,15 "notification",16 {17 id: "notif-123",18 title: "New message",19 body: "You have a new message",20 createdAt: new Date().toISOString(),21 }22);2324// Trigger activity feed event25await pusherServer.trigger(26 `org-${orgId}`,27 "activity",28 {29 type: "member_joined",30 actor: { name: "John Doe", avatar: "/avatar.png" },31 timestamp: new Date().toISOString(),32 }33);
Subscribe to channels and listen for events in your React components
1// src/lib/pusher/client.ts2import PusherClient from "pusher-js";34export const pusherClient = new PusherClient(5 process.env.NEXT_PUBLIC_PUSHER_KEY!,6 {7 cluster: process.env.NEXT_PUBLIC_PUSHER_CLUSTER!,8 }9);1011// In your component12"use client";13import { useEffect, useState } from "react";14import { pusherClient } from "@/lib/pusher/client";1516export function NotificationBell({ userId }: { userId: string }) {17 const [notifications, setNotifications] = useState([]);18 const [unreadCount, setUnreadCount] = useState(0);1920 useEffect(() => {21 const channel = pusherClient.subscribe(`user-${userId}`);2223 channel.bind("notification", (data: Notification) => {24 setNotifications((prev) => [data, ...prev]);25 setUnreadCount((prev) => prev + 1);26 });2728 return () => {29 channel.unbind_all();30 pusherClient.unsubscribe(`user-${userId}`);31 };32 }, [userId]);3334 return (35 <button className="relative">36 <BellIcon />37 {unreadCount > 0 && (38 <span className={cn('absolute -top-1 -right-1 bg-destructive text-destructive-foreground text-xs px-1', mode.radius)}>39 {unreadCount}40 </span>41 )}42 </button>43 );44}
Track which members are online in an organization
1// Client-side presence subscription2"use client";3import { useEffect, useState } from "react";4import { pusherClient } from "@/lib/pusher/client";56export function OnlineMembers({ orgId }: { orgId: string }) {7 const [members, setMembers] = useState<Member[]>([]);89 useEffect(() => {10 const channel = pusherClient.subscribe(`presence-org-${orgId}`);1112 channel.bind("pusher:subscription_succeeded", (data: any) => {13 setMembers(Object.values(data.members));14 });1516 channel.bind("pusher:member_added", (member: any) => {17 setMembers((prev) => [...prev, member.info]);18 });1920 channel.bind("pusher:member_removed", (member: any) => {21 setMembers((prev) => prev.filter((m) => m.id !== member.id));22 });2324 return () => {25 pusherClient.unsubscribe(`presence-org-${orgId}`);26 };27 }, [orgId]);2829 return (30 <div className="flex -space-x-2">31 {members.map((member) => (32 <img33 key={member.id}34 src={member.avatar}35 alt={member.name}36 className={cn('w-8 h-8 border-2 border-background', mode.radius)}37 />38 ))}39 </div>40 );41}
private-) for user-specific datapresence-) for tracking online status