Features
Notifications
In-app notifications generated on real app events.
TheShipStack includes an in-app notification system that generates notifications on meaningful events across the app.
What triggers notifications
| Event | Recipients |
|---|---|
| Workspace renamed | All members |
| Project created | All members |
| Project deleted | All members |
| Member role changed | Affected member |
| Member removed | Affected member |
| Subscription activated | Workspace owner |
| Plan changed | Workspace owner |
| Cancellation scheduled | Workspace owner |
| Payment failed | Workspace owner |
Sending notifications
Three helpers in lib/notify.ts cover the common fan-out patterns:
import { notifyUser, notifyOrgMembers, notifyOrgOwners } from '@/lib/notify'
// Notify a specific user
await notifyUser(userId, {
title: 'Your role has been updated',
body: 'You are now an admin in this workspace.',
href: '/dashboard/workspace/settings',
})
// Notify all members of a workspace
await notifyOrgMembers(orgId, {
title: 'Project deleted',
body: `"My Project" was deleted.`,
href: '/dashboard',
})
// Notify only the workspace owner (e.g. billing events)
await notifyOrgOwners(orgId, {
title: 'Payment failed',
body: 'Your latest invoice could not be charged. Update your payment method.',
href: '/dashboard/workspace/settings?tab=billing',
})Notification payload
| Field | Type | Description |
|---|---|---|
title | string | Short title shown in the notification list |
body | string | Full description |
href | string (optional) | Link the notification navigates to when clicked |
Adding notifications to your own actions
Call the appropriate helper at the end of your server action, after the main operation succeeds:
export async function publishPost(postId: string) {
const { orgId } = await requireOrg()
// ... your logic ...
await notifyOrgMembers(orgId, {
title: 'New post published',
body: `A new post is live.`,
href: `/dashboard/posts/${postId}`,
})
}