Message History
Persist messages to the database and load them on demand. Useful for chat rooms, activity feeds, and any channel where new users need to see past messages.
Persist a message
Pass { persist: true } when publishing:
channel.publish('message', {
userId: user.id,
text: 'Hello, room!',
timestamp: Date.now(),
}, { persist: true })Messages are stored in your project’s D1 database under the realtime_messages table.
Load history
const history = await channel.getHistory(50)
// Returns up to 50 most recent messages, newest firstWith a cursor (for pagination):
const firstPage = await channel.getHistory(50)
const oldest = firstPage[firstPage.length - 1]
const nextPage = await channel.getHistory(50, oldest.created_at)History message shape
interface HistoryMessage {
id: string
room_id: string // the channel topic
user_id: string
event: string // the event name you published
data: any // the payload you published
created_at: number // Unix timestamp (ms)
}Group chat example with history
import { useAerostack } from '@aerostack/react'
import { useEffect, useState } from 'react'
function ChatRoom({ roomId, userId }) {
const { realtime } = useAerostack()
const [messages, setMessages] = useState([])
const [channel, setChannel] = useState(null)
useEffect(() => {
const ch = realtime.channel(`chat/${roomId}`)
// Load history first
ch.getHistory(50).then(history => {
const formatted = history.reverse().map(m => ({
id: m.id,
userId: m.user_id,
text: m.data.text,
timestamp: m.created_at,
}))
setMessages(formatted)
})
ch
.on('message', ({ data }) => {
setMessages(prev => [...prev, {
id: Date.now().toString(),
userId: data.userId,
text: data.text,
timestamp: Date.now(),
}])
})
.subscribe()
setChannel(ch)
return () => ch.unsubscribe()
}, [realtime, roomId])
const sendMessage = (text) => {
channel?.publish('message', { userId, text }, { persist: true })
// Add optimistically
setMessages(prev => [...prev, {
id: Date.now().toString(),
userId,
text,
timestamp: Date.now(),
}])
}
return (
<div>
{messages.map(m => (
<div key={m.id}>{m.userId}: {m.text}</div>
))}
<button onClick={() => sendMessage('Hello!')}>Send</button>
</div>
)
}⚠️
History is fetched via REST (not WebSocket). Make sure your API key is configured in AerostackProvider so the history request is authenticated.
See the Group Chat example for a complete multi-room implementation with history, presence, and participant lists.