DBindly Docs
Advanced

Real-Time Reactivity

Enable real-time updates with SSE or polling support in DBindly.

DBindly's reactivity system enables real-time data updates. When data changes on the server, your UI automatically updates without requiring page refreshes or manual polling.

Real-time updates require a Business plan or higher. The SDK verifies your plan's entitlement before opening a connection; if the check fails, reactive mode stays off.

Quick Start

Enable reactivity in your initialization:

DBindly.init({
  apiUrl: 'https://your-api.com/api',
  apiKey: 'pk_live_xxx',
  reactive: true, // Enable real-time updates
});

Configuration Options

OptionTypeDefaultDescription
reactivebooleanfalseEnable real-time updates
reactiveModestring'auto'Connection mode: 'auto', 'sse', or 'polling'
sseUrlstring-SSE endpoint URL (defaults to {apiUrl}/subscribe if empty)
pollIntervalnumber5000Polling interval in milliseconds
onReactiveConnectfunction-Callback when connected
onReactiveDisconnectfunction-Callback when disconnected
onReactiveUpdatefunction-Callback when data updates

Connection Modes

In auto mode, DBindly tries connections in this order:

  1. SSE (Server-Sent Events) - Streaming one-way updates
  2. Polling - Fallback using periodic HTTP requests
DBindly.init({
  apiUrl: 'https://your-api.com/api',
  reactive: true,
  reactiveMode: 'auto', // Default
});

Note: WebSocket mode was removed in SDK v2.6.0. If you previously set reactiveMode: 'websocket', the SDK now treats it as 'sse' and logs a deprecation warning.

SSE Mode

Use Server-Sent Events:

DBindly.init({
  apiUrl: 'https://your-api.com/api',
  reactive: true,
  reactiveMode: 'sse',
});

How SSE works under the hood (SDK v2.7.0+)

  • The SDK opens a single EventSource connection to {apiUrl}/subscribe (override with sseUrl), passing your API key and the current subscription set (collections, dataIds) as query parameters.
  • When you subscribe or unsubscribe while connected, the SDK transparently reconnects with updated parameters — one connection always covers the whole subscription set.
  • The server cycles each connection every few minutes; the browser reconnects automatically and receives a fresh snapshot of all subscribed data, so no updates are lost across reconnects.
  • One SSE connection replaces per-item polling, so it consumes a single metered API call per connection cycle instead of one per item per pollInterval.

Polling Mode

Use HTTP polling as fallback:

DBindly.init({
  apiUrl: 'https://your-api.com/api',
  reactive: true,
  reactiveMode: 'polling',
  pollInterval: 3000, // Poll every 3 seconds
});

The dbind_reactive Attribute

Mark elements for automatic real-time updates:

<!-- Auto-subscribe to updates for this data ID -->
<div dbind_reactive="product-123">
  <h1 dbind_data="title"></h1>
  <p dbind_data="price" dbind_format="currency:USD"></p>
  <span dbind_data="stock"></span>
</div>

When product-123 is updated on the server, all elements inside this container automatically update.

Multiple Reactive Elements

<!-- Each reactive element subscribes independently -->
<div dbind_reactive="user-profile">
  <span dbind_data="name"></span>
</div>

<div dbind_reactive="notifications">
  <span dbind_data="count"></span>
</div>

<div dbind_reactive="stock-ticker">
  <span dbind_data="price" dbind_format="currency:USD"></span>
</div>

JavaScript API

Subscribe to Data Updates

// Subscribe with callback
const unsubscribe = DBindly.subscribe('product-123', (data, action) => {
  console.log('Update received:', data);
  console.log('Action:', action); // 'update' or 'delete'
});

// Later: unsubscribe
unsubscribe();

Subscribe to Collection Updates

// Subscribe to a collection
const unsubscribe = DBindly.subscribeCollection(
  'products',
  { limit: 10, sort: { field: 'price', direction: 'desc' } },
  (result, action) => {
    console.log('Collection updated:', result.data);
  }
);

Check Connection Status

const status = DBindly.getReactiveStatus();
console.log(status);
// {
//   connected: true,
//   mode: 'sse',
//   subscriptions: ['product-123', 'user-profile'],
//   collectionSubscriptions: ['products']
// }

Disconnect

// Disconnect and clean up all subscriptions
DBindly.disconnectReactive();

Event Listeners

Listen for reactive events on the document:

// When connected
document.addEventListener('dbindly:reactive-connect', (e) => {
  console.log('Connected via:', e.detail.mode);
});

// When disconnected
document.addEventListener('dbindly:reactive-disconnect', (e) => {
  console.log('Disconnected:', e.detail.mode, e.detail.reason);
});

// When data updates
document.addEventListener('dbindly:data-updated', (e) => {
  console.log('Data updated:', e.detail.dataId, e.detail.data);
});

// When data is deleted
document.addEventListener('dbindly:data-deleted', (e) => {
  console.log('Data deleted:', e.detail.dataId);
});

// When collection updates
document.addEventListener('dbindly:collection-updated', (e) => {
  console.log('Collection updated:', e.detail.slug);
});

Callbacks

Use configuration callbacks for centralized handling:

DBindly.init({
  apiUrl: 'https://your-api.com/api',
  reactive: true,
  onReactiveConnect: ({ mode }) => {
    console.log('Connected via', mode);
    showToast('Real-time updates enabled');
  },
  onReactiveDisconnect: ({ mode, code }) => {
    console.log('Disconnected from', mode);
    showToast('Connection lost, reconnecting...');
  },
  onReactiveUpdate: ({ dataId, data, action }) => {
    console.log('Update:', dataId, action);
    // Flash updated elements
    document.querySelectorAll(`[dbind_reactive="${dataId}"]`)
      .forEach(el => el.classList.add('dbindly-updated'));
  },
});

Update Animations

DBindly includes built-in CSS classes for update animations:

/* Applied during update */
.dbindly-updating {
  opacity: 0.7;
  transition: opacity 0.15s ease;
}

/* Flash effect after update */
.dbindly-updated {
  animation: dbindly-flash 0.5s ease;
}

@keyframes dbindly-flash {
  0% { background-color: rgba(34, 197, 94, 0.2); }
  100% { background-color: transparent; }
}

Customize these in your own CSS:

/* Custom update flash */
.dbindly-updated {
  animation: my-flash 0.3s ease;
}

@keyframes my-flash {
  0% { box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5); }
  100% { box-shadow: none; }
}

Reactive Attributes Reference

AttributeReactiveDescription
dbind_dataYesText content updates in real-time
dbind_hrefYesURL updates in real-time
dbind_srcYesImage source updates in real-time
dbind_altYesAlt text updates in real-time
dbind_classYesCSS classes update in real-time
dbind_styleYesInline styles update in real-time
dbind_showYesVisibility toggles in real-time
dbind_hideYesVisibility toggles in real-time
dbind_ifYesConditional display in real-time
dbind_repeatYesLists re-render in real-time
dbind_collectionYesCollections sync in real-time
dbind_computeYesComputed values recalculate
dbind_reactive-Marks element for auto-subscription

Best Practices

1. Use Specific Subscriptions

Subscribe only to the data you need:

// Good: Subscribe to specific items
DBindly.subscribe('product-123');
DBindly.subscribe('cart-total');

// Avoid: Subscribing to everything

2. Unsubscribe When Done

Clean up subscriptions when components unmount:

// In a React component
useEffect(() => {
  const unsubscribe = DBindly.subscribe('data-id', callback);
  return () => unsubscribe();
}, []);

3. Handle Disconnections

Always handle disconnection scenarios:

DBindly.init({
  reactive: true,
  onReactiveDisconnect: () => {
    showNotification('Connection lost. Data may be stale.');
  },
});

4. Use Polling for Critical Data

For critical data where updates must not be missed:

DBindly.init({
  reactive: true,
  reactiveMode: 'polling',
  pollInterval: 2000, // Poll every 2 seconds
});

Server Integration

No server-side integration is required. Every write path into a collection — dashboard edits, CSV imports, webhook ingestion (POST /webhooks/collections/:slug), and source URL polling — automatically marks the collection as changed, and connected SSE clients receive the update within a couple of seconds.

Troubleshooting

Connection Not Establishing

  1. Check that reactive: true is set
  2. Verify the SSE endpoint is accessible (your plan must include reactive mode)
  3. Check browser console for connection errors
  4. Try forcing reactiveMode: 'polling' as fallback

Updates Not Showing

  1. Verify the dbind_reactive attribute matches the data ID
  2. Use DBindly.getReactiveStatus() to verify subscriptions
  3. Enable debug: true to see reactive logs (including SSE events)
  4. Confirm the data is actually changing (check the dashboard)

Performance Issues

  1. Reduce the number of active subscriptions
  2. Increase pollInterval if using polling
  3. Use collection subscriptions instead of individual items
  4. Consider pagination for large collections