Skip to Content
GuidesClient GuidesOffline Handling

Offline Handling

Monitor network state and handle offline scenarios gracefully.

Connection State

Use useConnectionState() to monitor sync status:

import { observer, useConnectionState } from '@gluonic/client' const SyncIndicator = observer(() => { const { isOnline, // Network available? isSyncing, // Currently syncing? queueLength, // Pending mutations lastSync // Last successful sync time } = useConnectionState() if (!isOnline) { return <Badge variant="warning">Offline</Badge> } if (isSyncing) { return <Badge variant="info">Syncing...</Badge> } if (queueLength > 0) { return <Badge variant="warning">{queueLength} pending</Badge> } return <Badge variant="success">Synced ✓</Badge> })

Network Detection

Gluonic tracks network state automatically:

// React Native import NetInfo from '@react-native-community/netinfo' // Gluonic integrates automatically // Updates store.networkEnabled // Web // Uses navigator.onLine // Updates store.networkEnabled

Queue Management

View Pending Mutations

const PendingChanges = observer(() => { const store = useStore() const queue = store.storage.listTx() // Async, call in useEffect return ( <div> <h3>Pending Changes ({queue.length})</h3> {queue.map(tx => ( <div key={tx.id}> {tx.op} {tx.type}:{tx.modelId} </div> ))} </div> ) })

Clear Queue

// Clear all pending mutations (careful!) await store.storage.clearTxQueue() // Or clear specific transaction await store.storage.dequeueTx(txId)

Offline-First Patterns

Optimistic Actions

const LikeButton = observer(({ postId }) => { const store = useStore() const post = useModel<Post>('post', postId) const handleLike = async () => { // Works offline! Syncs when back online await store.save('post', postId, { likes: (post.likes || 0) + 1 }) } return <button onClick={handleLike}>❤️ {post.likes}</button> })

Disable When Offline

const PublishButton = observer(({ post }) => { const { isOnline } = useConnectionState() const handlePublish = async () => { await store.save('post', post.id, { published: true }) } return ( <button onClick={handlePublish} disabled={!isOnline} > {isOnline ? 'Publish' : 'Offline - Cannot Publish'} </button> ) })

Show Offline Banner

const App = observer(() => { const { isOnline, queueLength } = useConnectionState() return ( <div> {!isOnline && ( <Banner variant="warning"> You're offline. {queueLength} changes will sync when back online. </Banner> )} <MainContent /> </div> ) })

Sync Control

Manual Sync

const SyncButton = () => { const store = useStore() const handleSync = async () => { await store.catchUp() // Delta sync + WebSocket reconnect } return <button onClick={handleSync}>Sync Now</button> }

Pause/Resume Sync

// Pause (e.g., to save battery) store.networkEnabled = false // Resume store.networkEnabled = true store.catchUp()

API Reference: observer · useStore · useModel

Best Practices

DO ✅

  • Show offline indicator subtly (small badge)
  • Allow all operations offline
  • Queue mutations for later sync
  • Notify when back online
  • Show pending changes count

DON’T ❌

  • Block features when offline
  • Show errors for offline state
  • Clear local data on disconnect
  • Require network for reads
  • Disable UI when offline

Next Steps

Last updated on