Chat
1:1 & group messaging with realtime events
The chat block turns on a complete in-app messaging system: direct (1:1) and group conversations, message editing and deletion, typing indicators, read receipts with unread counts, and file attachments — all served over REST routes under basePath, with realtime events broadcast through the pubsub block.
Like everything in Nucleus, it pairs with a ready frontend: the ChatPanel component and useChat hook consume these routes and events directly, so a working messenger is a config key plus one component.
Configuration#
Defaults are production-sensible — enabling the block is usually enough. The knobs below tune group size, message limits and which social signals are broadcast.
1{2 "chat": {3 "enabled": true,4 "basePath": "/chat",5 "groupsEnabled": true,6 "maxGroupParticipants": 100,7 "maxMessageLength": 8000,8 "typingIndicators": true,9 "readReceipts": true,10 "attachments": { "enabled": true, "maxPerMessage": 5 }11 }12}enabledbooleanOptionalMaster switch. Routes register only when enabled and a database is configured.
falsebasePathstringOptionalMount point for the chat REST routes.
"/chat"groupsEnabledbooleanOptionalAllow group conversations in addition to 1:1 direct chats. Groups require a title and get owner/admin/member roles.
truemaxGroupParticipantsnumberOptionalCap on participants per group conversation.
256maxMessageLengthnumberOptionalMaximum message length in characters, enforced on send and edit.
8000editingEnabled / deletionEnabledbooleanOptionalLet senders edit or delete their own messages. Deletion is soft — content is cleared and deletedAt set, so the conversation history stays coherent.
truetypingIndicators / readReceiptsbooleanOptionalBroadcast typing and read events to other participants over the realtime channel. Read receipts also drive each participant's unreadCount.
truerealtimeTopicPrefixstringOptionalTopic prefix for the realtime events listed below.
"chat"messagePageSizenumberOptionalMessages per history page. The messages endpoint cursor-paginates newest-first with limit clamped to 1–100.
50attachments{ enabled?, maxPerMessage?, maxFileSizeBytes?, allowedMimeTypes? }OptionalFile attachments on messages. Requires storage.enabled and storage.cdn.enabled; since enabled defaults to true, attachments switch on automatically once storage + CDN are configured. Size and MIME validation come from the storage block.
Endpoints#
All under basePath; every route reads the authenticated user from the request (401 without one). Conversation responses include participants, your participant record and your unreadCount.
GET /conversationslistYour conversations, ordered by last activity. limit (default 30, max 100) + offset.
POST /conversationscreateDirect ({ targetUserId }) or group ({ type: 'group', title, participantIds }). Direct pairs are deduplicated — re-creating an existing pair returns the existing conversation.
GET /conversations/:id/messageshistoryNewest-first cursor pagination: limit + before=<messageId> returns { messages, hasMore }.
POST /conversations/:id/messagessendSend text and/or pre-uploaded attachment ids, optionally replying to another message (replyToId) with idempotency via clientMessageId. A multipart sibling — POST .../messages/upload — uploads files and sends in one call.
POST /conversations/:id/read · /typingsignalsMark the conversation read (resets your unreadCount) and broadcast typing state.
PATCH · DELETE /messages/:idedit / deleteEdit or soft-delete your own messages — sender-only, enforced server-side.
POST · DELETE /conversations/:id/participantsmembershipAdd or remove group participants. Only owner/admin can manage others; any member can leave.
From the frontend#
The frontend kit ships a complete messenger UI on top of these routes — conversation list, message thread, composer with attachments, typing and presence — themeable like every Nucleus component.
ChatPanelcomponentThe full messenger surface. Pairs with useChat / useChatStore and the NewConversationModal; styling via chatPanelTheme / extendChatPanelTheme.
usePubSubhookThe realtime hook the panel uses under the hood — subscribe to the chat topics yourself if you build a custom UI.
Related sections