Remote Data
Use remote when events or resources are too large to ship up front, or when the scheduler must load only the visible date range.
grid.eventScheduler = { view: 'resourceTimeline', weekStartDate: '2026-06-08', remote: { enabled: true, loadEvents: async ({ dateRange, resourceIds }) => { const params = new URLSearchParams({ start: dateRange.start, end: dateRange.end, resources: resourceIds?.join(',') ?? '', }); const response = await fetch(`/api/scheduler/events?${params}`); return { events: await response.json() }; }, loadResources: async () => { const response = await fetch('/api/scheduler/resources'); return { resources: await response.json() }; }, commitMutation: async (request) => { const response = await fetch('/api/scheduler/mutations', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(request), }); if (!response.ok) { throw new Error('Save failed'); } return { accepted: true, events: await response.json() }; }, },};The resource timeline demo includes remote-mode controls for refresh, load-more resources, and simulated save failure.
Remote Options and State
Section titled “Remote Options and State”Remote mode can load events, resources, availability, unassigned demand, and coverage for the visible range. It can also validate and commit accepted mutations.
const eventScheduler = { view: 'resourceTimeline', weekStartDate: '2026-06-08', dateRange: { start: '2026-06-08', end: '2026-06-14' }, remote: { enabled: true, mode: 'remote', debounceMs: 150, overscanDays: 1, resourcePageSize: 50, loadEvents: ({ dateRange, filters, signal }) => api.loadEvents({ dateRange, filters }, { signal }), loadResources: ({ cursor, limit, signal }) => api.loadResources({ cursor, limit }, { signal }), loadAvailability: ({ dateRange, signal }) => api.loadAvailability({ dateRange }, { signal }), loadCoverage: ({ dateRange, signal }) => api.loadCoverage({ dateRange }, { signal }), validateMutation: ({ action, event, previousEvent }) => api.validateScheduleChange({ action, event, previousEvent }), commitMutation: ({ action, event, previousEvent, events }) => api.saveScheduleChange({ action, event, previousEvent, events }), optimistic: true, rollbackOnError: true, refreshPolicy: 'visible-range', },};Remote modes:
| Mode | Behavior |
| :-- | :-- |
| local | Remote controller is effectively off unless enabled hooks are used by the host. |
| remote | Visible data is loaded through remote hooks. |
| hybrid | Host can combine local side-channel data with remote range data. |
Remote state is available from scheduler.getRemoteState(). The plugin emits:
| Event | Purpose |
| :-- | :-- |
| event-scheduler-remote-load-start | A visible-range load begins. |
| event-scheduler-remote-load-success | A load target resolves. |
| event-scheduler-remote-load-error | A load target fails. |
| event-scheduler-remote-mutation-pending | A remote mutation starts. |
| event-scheduler-remote-mutation-committed | The backend accepts a mutation. |
| event-scheduler-remote-mutation-rejected | The backend rejects a mutation. |
| event-scheduler-remote-state-change | Loading, error, pending, paging, or empty state changes. |
Use scheduler.refreshVisibleRange() to reload the current range and scheduler.loadMoreResources() when paged resources report hasMoreResources.