Skip to content

React SDK — Realtime

Access the realtime client via the useAerostack hook.

import { useAerostack } from '@aerostack/react'
const { realtime } = useAerostack()

The realtime object is a RealtimeClient instance — connected automatically when AerostackProvider mounts.

Get (or create) a subscription for a topic. Returns a RealtimeSubscription.

const channel = realtime.channel('orders') // DB table subscription
const channel = realtime.channel('chat/general') // Custom pub/sub channel
const channel = realtime.channel('ai-chat/session-1') // Session channel
ParameterTypeDescription
topicstringChannel topic. No slash → DB table subscription. With slash → custom channel.
options.filterRecord<string, any>Optional server-side filter

Subscribe to connection status changes. Returns an unsubscribe function.

const unsubscribe = realtime.onStatusChange((status) => {
// 'idle' | 'connecting' | 'connected' | 'reconnecting' | 'disconnected'
setConnectionStatus(status)
})
// Cleanup:
unsubscribe()

realtime.connect() / realtime.disconnect()

Section titled “realtime.connect() / realtime.disconnect()”

Manually connect or disconnect. The SDK connects automatically on mount.

await realtime.connect()
realtime.disconnect()

Update the auth token on a live connection (e.g. after token refresh).

realtime.setToken(newAccessToken)

Returned by realtime.channel().

Register a callback for an event. Returns this (chainable).

channel.on('INSERT', ({ data }) => { ... })
channel.on('UPDATE', ({ data, old }) => { ... })
channel.on('DELETE', ({ data }) => { ... })
channel.on('*', (payload) => { ... }) // All events
// Custom named events (pub/sub):
channel.on('todo:created', ({ data }) => { ... })
channel.on('presence:join', ({ data }) => { ... })

Payload shape:

interface RealtimePayload<T = any> {
type: 'db_change' | 'event'
topic: string
operation?: 'INSERT' | 'UPDATE' | 'DELETE' // DB changes
event?: string // Custom event name
data: T // New/current value
old?: T // Previous value (UPDATE/DELETE)
userId?: string
timestamp?: number | string
}

Remove a specific event listener.

const handler = ({ data }) => setItems(prev => [...prev, data])
channel.on('item:added', handler)
// later:
channel.off('item:added', handler)

Send the subscribe message to the server. Call after registering all .on() listeners.

channel.on('INSERT', handler).subscribe()

Send unsubscribe and clear all listeners. Call on component cleanup.

return () => channel.unsubscribe()

Broadcast a custom event to all channel subscribers.

channel.publish('todo:created', { id: '123', text: 'Buy milk' })
channel.publish('message', { text: 'Hello!' }, { persist: true })
ParameterTypeDescription
eventstringEvent name
dataanyPayload to broadcast
options.persistbooleanStore message in DB for history

Announce your presence on this channel.

channel.track({
userId: user.id,
name: user.name,
color: '#FF5733',
status: 'online',
})

Remove your presence from this channel. Broadcasts presence:leave.

channel.untrack()

Fetch persisted messages. Requires previous publishes with { persist: true }.

const messages = await channel.getHistory(50)
// messages: HistoryMessage[]
// Paginate:
const older = await channel.getHistory(50, messages[messages.length - 1].created_at)

HistoryMessage shape:

interface HistoryMessage {
id: string
room_id: string
user_id: string
event: string
data: any
created_at: number
}

import { useAerostack } from '@aerostack/react'
function LiveData() {
const { realtime } = useAerostack()
const [items, setItems] = useState([])
useEffect(() => {
const channel = realtime.channel('items')
channel
.on('INSERT', ({ data }) => setItems(prev => [...prev, data]))
.on('UPDATE', ({ data }) => setItems(prev => prev.map(i => i.id === data.id ? data : i)))
.on('DELETE', ({ data }) => setItems(prev => prev.filter(i => i.id !== data.id)))
.subscribe()
return () => channel.unsubscribe()
}, [realtime])
return <ul>{items.map(i => <li key={i.id}>{i.name}</li>)}</ul>
}