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.
RealtimeClient methods
realtime.channel(topic, options?)
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| Parameter | Type | Description |
|---|---|---|
topic | string | Channel topic. No slash → DB table subscription. With slash → custom channel. |
options.filter | Record<string, any> | Optional server-side filter |
realtime.onStatusChange(callback)
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()
Manually connect or disconnect. The SDK connects automatically on mount.
await realtime.connect()
realtime.disconnect()realtime.setToken(newToken)
Update the auth token on a live connection (e.g. after token refresh).
realtime.setToken(newAccessToken)RealtimeSubscription methods
Returned by realtime.channel().
.on(event, callback)
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
}.off(event, callback)
Remove a specific event listener.
const handler = ({ data }) => setItems(prev => [...prev, data])
channel.on('item:added', handler)
// later:
channel.off('item:added', handler).subscribe()
Send the subscribe message to the server. Call after registering all .on() listeners.
channel.on('INSERT', handler).subscribe().unsubscribe()
Send unsubscribe and clear all listeners. Call on component cleanup.
return () => channel.unsubscribe().publish(event, data, options?)
Broadcast a custom event to all channel subscribers.
channel.publish('todo:created', { id: '123', text: 'Buy milk' })
channel.publish('message', { text: 'Hello!' }, { persist: true })| Parameter | Type | Description |
|---|---|---|
event | string | Event name |
data | any | Payload to broadcast |
options.persist | boolean | Store message in DB for history |
.track(state)
Announce your presence on this channel.
channel.track({
userId: user.id,
name: user.name,
color: '#FF5733',
status: 'online',
}).untrack()
Remove your presence from this channel. Broadcasts presence:leave.
channel.untrack().getHistory(limit?, before?)
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
}React pattern: useEffect subscription
import { useAerostack } from '@aerostack/react'
import { useEffect, useState } from '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>
}