Here is a message from two days ago.
Chat - Date divider
Group messages by day with inline separators inside the chat thread.
Overview
Date dividers help users orient themselves in long conversations that span multiple days by grouping messages under a day label.
The date divider appears between messages whose createdAt values fall on different calendar days.
It is an opt-in feature: nothing renders until you enable it, and you can also embed the component directly in custom layouts.
Enabling date dividers
Pass features={{ dateDivider: true }} to ChatBox (or to a standalone ChatMessageList) to render dividers at every day boundary:
<ChatBox adapter={adapter} features={{ dateDivider: true }} />
Once enabled, customize the rendered component with the dateDivider slot and forward props (such as a custom formatDate) through slotProps.dateDivider:
<ChatBox
adapter={adapter}
features={{ dateDivider: true }}
slotProps={{
dateDivider: {
formatDate: (date) =>
date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }),
},
}}
/>
formatDate receives a native Date (the message's createdAt) and can return any ReactNode. When omitted, the label defaults to date.toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' }) — for example May 3, 2026 in an en-US locale.
The demo below enables the feature on a conversation spanning three days — a divider appears at each day boundary:
Customizing divider placement
By default a divider renders above a message whose createdAt falls on a different UTC calendar day than the previous message's (see Overview).
To group messages differently, pass a shouldShowDivider predicate through slotProps.dateDivider.
It receives { message, previousMessage, index, date, previousDate } — where date/previousDate are the parsed createdAt values (null when missing or invalid) — and returns true to render a divider above the message.
Divider by week
This recipe groups messages by ISO week instead of by day, labeling each group with the Monday that starts it:
function startOfWeekIso(date: Date) {
const d = new Date(date);
d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 6) % 7)); // back to Monday
return d.toISOString().slice(0, 10);
}
const shouldShowDivider = ({ date, previousDate }) =>
date != null &&
previousDate != null &&
startOfWeekIso(date) !== startOfWeekIso(previousDate);
Divider every N messages
The predicate can ignore dates entirely. This rule inserts a divider every five messages:
<ChatBox
adapter={adapter}
features={{ dateDivider: true }}
slotProps={{
dateDivider: {
shouldShowDivider: ({ index }) => index > 0 && index % 5 === 0,
},
}}
/>
The label still derives from each message's own createdAt, so pair the predicate with a custom formatDate to relabel it.
When a message has no createdAt, its label renders empty — guard for that case in the predicate (or in formatDate) if your data can omit timestamps.
The same hook supports any rule: for example, group by the viewer's local day instead of the default UTC day by comparing local-date strings inside the predicate.
Interactive playground
The playground below renders the divider between two messages and lets you change formatDate and the second message's createdAt:
ChatDateDivider
Day separator between message clusters — uses caption + divider tokens.
Sent lastYear

Sent today
See also
- Unread marker — the other opt-in inline separator.
- Structure — the slot reference, including the
dateDividerslot row. - Messages — feature flags on the message list.
API
See the documentation below for a complete reference to all of the props and classes available to the components mentioned here.