Skip to content

Google Calendar Sync

Google Calendar Sync requires the GoogleCalendarSync entitlement. The snippets on this page are frontend browser code and use ScheduleXBrowserClient with a short-lived frontend token. The Schedule-X Cloud backend stores provider credentials and performs synchronization; Google credentials never belong in your frontend.

For the complete first-time setup, start with Quickstart With Calendar Sync.

import {
ScheduleXBrowserClient,
createScheduleXCloudCalendar,
} from '@schedule-x-cloud/sdk'
const client = new ScheduleXBrowserClient({
token: frontendToken.token,
})

Register the application’s exact origin for the selected environment under Settings → OAuth return origins in the Cloud console. The return URL may use any path and query on that origin. HTTPS is required except for localhost.

const { url } = await client.integrations.googleCalendar.getConnectUrl({
returnUrl: window.location.href,
})
window.location.assign(url)

After Google redirects back, the high-level calendar can own the import and its loading lifecycle:

const calendarApp = createScheduleXCloudCalendar({
getFrontendToken,
initialProviderSync: true,
})

The calendar continues polling when the initial wait times out. Its public calendarApp.scheduleXCloud.state.providerSync snapshot includes the current statuses, pending and failed counts, and whether the first wait timed out.

Use client.integrations.googleCalendar.syncAllProviderCalendars() directly when you need synchronization without rendering the high-level calendar.

For selective sync:

const connections = await client.integrations.googleCalendar.listConnections()
const calendars = await client.integrations.googleCalendar.listProviderCalendars(
connections[0].id
)
await client.integrations.googleCalendar.enableCalendarSync(
connections[0].id,
calendars[0].id,
{ name: calendars[0].name }
)

Synced calendars appear in client.scheduleX.getCalendarAppConfig(). Cloud imports Google’s calendar background and foreground colors and derives a complete Schedule-X light/dark palette. It also preserves Google’s access role and primary-calendar signal so the config can expose correct capabilities and choose a sensible default. Google CalendarList webhooks keep linked calendar names and colors current when they change in Google. For linked Google calendars, sidebar name and color changes are written to that user’s Google CalendarList entry as a title override and RGB colors; they do not rename shared calendar metadata for other users. The confirmed provider values are then reconciled back into the Schedule-X calendar so both clients stay consistent.

Real-time updates are enabled by default when you use the Schedule-X Cloud calendar preset. The browser SDK opens an authenticated change stream with its short-lived frontend token. When Cloud data changes, the preset refetches the permission-shaped calendar configuration and updates the mounted calendar. Your application does not need to poll.

The same flow covers:

  • events created, updated, or deleted in Schedule-X Cloud;
  • event changes received from Google Calendar webhooks;
  • Google calendar names, colors, access roles, and primary-calendar metadata;
  • calendar presentation changes made through the browser SDK.

Google CalendarList notifications trigger an immediate metadata read plus short follow-up reads, because Google can deliver a notification before the updated title or color is available through its API. Periodic reconciliation provides a fallback for dropped provider notifications.

The preset starts its subscription automatically. React integrations should pair its lifecycle with the mounted calendar so development Strict Mode can resume the subscription after its extra cleanup cycle:

useEffect(() => {
preset.startLiveUpdates()
return () => preset.dispose()
}, [preset])

Set liveUpdates: false when creating the preset only if your application needs to manage refreshes itself. Lower-level integrations can subscribe with client.scheduleX.subscribeToChanges(...) and refetch config when notified.

await client.integrations.googleCalendar.getSyncStatus()
await client.integrations.googleCalendar.disconnect(connectionId)
await client.integrations.googleCalendar.enableAllProviderCalendars()

Sync statuses are PendingInitialSync, Syncing, Synced, Error, and Disabled.