Notifications
Send targeted or broadcast in-app notifications and understand the user notification center.
The starter kit includes a database-backed notification center for signed-in users and an administrative workflow for sending and reviewing notifications.
What Ships
Users receive a notification bell in the expanded application sidebar and in the mobile navigation drawer. The popover includes:
- An unread count on the bell
- All and Unread tabs
- Information, success and warning states
- Expandable message content
- Optional internal action links
- Individual and bulk mark-as-read actions
- Loading, empty and recoverable error states
The bell is hidden when the desktop sidebar is collapsed so it does not compete with the compact navigation rail.
Platform administrators also receive /dashboard/admin/notifications. The
page provides search, type and read-state filters, pagination, a notification
details sheet, row selection and confirmed bulk deletion.
Send a Notification
- Sign in with a platform
adminaccount. - Open Admin Panel → Notifications.
- Select Send notification.
- Choose one active user or all active users.
- Enter a title, message and type.
- Optionally add an internal application path such as
/dashboard/settings?tab=billing. - Review the audience in the confirmation dialog and send.
Banned users are excluded from recipient search and broadcasts. Broadcasts are inserted in batches inside a database transaction.
Action URLs must be internal paths. The shared getSafeRedirectPath utility
rejects external, protocol-relative and malformed values before creation, and
the notification center validates the stored path again before navigation.
Database Model
Each recipient gets one notification row. It stores:
userIdfor the recipient- optional
createdByIdfor the administrator who sent it title,messageandtype- optional
actionUrl - nullable
readAt createdAtandupdatedAt
The schema indexes the recipient with creation time for chronological listing
and the recipient with read time for unread queries. Deleting a user cascades
their notifications. Deleting a creator preserves delivered notifications and
sets createdById to NULL.
Apply the checked-in migration before running the updated application:
npm run db:migrateNo new environment variable is required.
User Procedures
The notification tRPC router exposes:
| Procedure | Purpose |
|---|---|
notification.list | List the current user's recent messages |
notification.unreadCount | Count the current user's unread rows |
notification.get | Read one owned notification |
notification.markRead | Mark one owned row as read |
notification.markAllRead | Mark all current-user rows as read |
Every database condition includes ctx.user.id. A caller cannot read or
change another user's notification by supplying its ID.
Admin Procedures
The admin.notification router uses protectedAdminProcedure and exposes:
| Procedure | Purpose |
|---|---|
admin.notification.list | Search and filter delivery history |
admin.notification.recipients | Find active recipients |
admin.notification.create | Send to one user or broadcast |
admin.notification.bulkDelete | Delete up to 100 selected rows |
Deleting a notification removes it from the recipient's notification center. The admin interface confirms destructive row and bulk actions before calling the mutation.
Create Notifications from Application Code
Product events can create notification rows directly in server-only code. Keep the same boundaries as the admin workflow:
- Resolve recipients from trusted server state.
- Validate an action with
getSafeRedirectPathor storeNULL. - Insert one row per recipient.
- Keep external email or push delivery in a separate queue or integration.
The shipped release is an in-app, database-backed system. It does not provide real-time push delivery. Add polling, server-sent events or a realtime provider only when the product requires live arrival.
Customize the Notification Center
The main files are:
components/notifications/notification-center.tsxcomponents/notifications/notification-icon.tsxcomponents/admin/notifications/admin-notifications.tsxcomponents/admin/notifications/create-notification-modal.tsxcomponents/admin/notifications/notification-details-modal.tsxschemas/notification-schemas.tstrpc/routers/notification/index.tstrpc/routers/admin/admin-notification-router.ts
Keep the user router scoped to the authenticated user and keep management
procedures behind protectedAdminProcedure when changing the presentation or
adding notification types.