MenuLive

<MenuLive> renders a navigation menu where each item shows a badge with the count of unread realtime events since the user last visited that route. The count resets automatically when the user navigates to the resource.

Installation

pnpm dlx shadcn@latest add @shadmin/menu-live

Usage

import { MenuLive } from "@/components/realtime";
import { Users, FileText } from "lucide-react";
 
export function AppMenu() {
  return (
    <MenuLive
      items={[
        { to: "/posts", resource: "posts", primaryText: "Posts", icon: <FileText /> },
        { to: "/users", resource: "users", primaryText: "Users", icon: <Users /> },
      ]}
    />
  );
}

Single item

Use <MenuLiveItemLink> directly when you need just one live link:

import { MenuLiveItemLink } from "@/components/realtime";
 
<MenuLiveItemLink
  to="/posts"
  resource="posts"
  primaryText="Posts"
  events={["created"]}
  badgeLabel={(n) => `${n} new`}
/>

Props

PropRequiredTypeDescription
itemsRequiredReadonlyArray<MenuLiveItemLinkProps>Array of item descriptors
PropRequiredTypeDefaultDescription
toRequiredstringTarget route (link href)
resourceRequiredstringResource name used for the subscription topic
primaryTextRequiredReactNodeLabel shown in the menu
iconOptionalReactNodeIcon shown before the label
eventsOptionalRealtimeEventType[]["created"]Which event types increment the counter
badgeLabelOptional(count: number) => ReactNodecount (capped at "99+")Custom badge content

Notes

  • The unread count is stored in the ra-core Store under key realtime.unread.<resource>, so it survives component re-renders but is cleared on page reload.
  • The counter resets to zero automatically when pathname.startsWith(to) — i.e. when the user is on the resource route.
  • By default only "created" events increment the counter. Pass events={["created", "updated"]} to include updates.
  • The badge is not rendered when the count is zero.