Skip to Content
v3is here! Temporal API, timezones, and more 🥳
DocsCalendarPluginsEvent Recurrence

Event recurrence

ℹ️ Important note before getting started

This plugin enables you to create recurring events according to the iCalendar specification. Please note, however, that this plugin only offers a partial implementation of the specification. There are 2 reasons for this:

  1. Some rules just haven’t been implemented yet. If there is a rule that you would like to see implemented, and you think this rule could be updated in a predictable way using drag & drop or resize, please open an issue on GitHub.
  2. Some iCalendar rules don’t make sense in an interactive calendar. Consider for example FREQ=MONTHLY;BYDAY=1SU,4TH; COUNT=20 where dragging one occurrence might offset the other occurrences in a non-symmetrical way, which might not have been intended when creating the rule.

If you need an almost full implementation of the iCalendar spec, you can use the rrule library instead of this plugin. Here’s an example of how to do so. However, this only works if you’re merely using the calendar to display events. If you want to use interactive features like drag & drop or resizing, you cannot use the external rrule library.

Installation

npm install @schedule-x/event-recurrence

Usage

import { createEventRecurrencePlugin } from "@schedule-x/event-recurrence"; const calendar = createCalendar({ // ... other config options plugins: [ createEventRecurrencePlugin() ], events: [ { id: 123, title: 'Bi-Weekly Event Monday and Wednesday', start: Temporal.ZonedDateTime.from('2024-02-05T14:00:00+01:00[Europe/Berlin]'), end: Temporal.ZonedDateTime.from('2024-02-05T15:00:00+01:00[Europe/Berlin]'), rrule: 'FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE;UNTIL=20240229T235959' }, { id: 456, title: 'Weekly Event on 4 occasions', start: Temporal.PlainDate.from('2024-02-03'), end: Temporal.PlainDate.from('2024-02-03'), rrule: 'FREQ=WEEKLY;COUNT=4' }, { id: 789, title: 'Daily event 5 times', start: Temporal.ZonedDateTime.from('2024-02-05T12:00:00+01:00[Europe/Berlin]'), end: Temporal.ZonedDateTime.from('2024-02-05T13:55:00+01:00[Europe/Berlin]'), rrule: 'FREQ=DAILY;COUNT=5', calendarId: 'personal', }, { id: 121314, title: 'Daily event mo-fr 10 times', start: Temporal.ZonedDateTime.from('2024-02-05T12:00:00+01:00[Europe/Berlin]'), end: Temporal.ZonedDateTime.from('2024-02-05T13:55:00+01:00[Europe/Berlin]'), rrule: 'FREQ=DAILY;COUNT=10;BYDAY=MO,TU,WE,TH,FR', calendarId: 'work', }, { id: 141617, title: 'Monthly event on the 7th 5 times', start: Temporal.ZonedDateTime.from('2024-02-07T16:00:00+01:00[Europe/Berlin]'), end: Temporal.ZonedDateTime.from('2024-02-07T17:55:00+01:00[Europe/Berlin]'), rrule: 'FREQ=MONTHLY;COUNT=5', }, { rrule: 'FREQ=YEARLY;COUNT=5', title: 'Event on the 8th of February for 5 years', start: Temporal.ZonedDateTime.from('2024-02-08T16:00:00+01:00[Europe/Berlin]'), end: Temporal.ZonedDateTime.from('2024-02-08T17:55:00+01:00[Europe/Berlin]'), id: 181920 } ] });

Supported rules

RuleSupported valuesRequired
FREQDAILY, WEEKLY, MONTHLY or YEARLYYes
COUNTNumberNo
INTERVALNumberNo
BYDAY - compatible with DAILY and WEEKLYMO, TU, WE, TH, FR, SA, SUNo
BYMONTHDAY - compatible with MONTHLY(Single) Positive integer 1-31. Does not support list of values, since such lists cannot be updated in a predictable way using drag & drop.No
UNTILFloating date, for example 20240101 or date-time 20240101T120000No
WKSTMO, TU, WE, TH, FR, SA, SUNo

exdate

You can exclude certain dates or date-times from a recurrence set using the exdate rule. The expected format is RFC5455 floating date (e.g. 20240101) or datetime (e.g. 20240101T120000). For example:

const recurringEventWithExclusions = { id: 123, title: 'Weekly event', start: Temporal.ZonedDateTime.from('2024-02-05T14:00:00+01:00[Europe/Berlin]'), end: Temporal.ZonedDateTime.from('2024-02-05T15:00:00+01:00[Europe/Berlin]'), // will create a recurrence set of 3 events: 2024-02-05 14:00, 2024-02-26 14:00, 2024-03-04 14:00 rrule: 'FREQ=WEEKLY;COUNT=5', exdate: [ '20240212T140000', '20240219T140000' ] }

Events service

When using this plugin, you can no longer use the regular events service plugin. Instead, you now need to import the events service plugin from this package:

import { createEventRecurrencePlugin, createEventsServicePlugin } from "@schedule-x/event-recurrence"; const recurrencePlugin = createEventRecurrencePlugin(); const eventsServicePlugin = createEventsServicePlugin(); const calendar = createCalendar({ /* other config */ plugins: [ recurrencePlugin, eventsServicePlugin ] }); calendar.render(document.getElementById('calendar')); // Add an event eventsServicePlugin.add({ id: 1, title: 'New event', start: Temporal.ZonedDateTime.from('2024-02-05T14:00:00+01:00[Europe/Berlin]'), end: Temporal.ZonedDateTime.from('2024-02-05T15:00:00+01:00[Europe/Berlin]'), rrule: 'FREQ=WEEKLY;COUNT=3' }); // Update eventsServicePlugin.update({ id: 1, title: 'New event', start: Temporal.ZonedDateTime.from('2024-02-05T14:00:00+01:00[Europe/Berlin]'), end: Temporal.ZonedDateTime.from('2024-02-05T15:00:00+01:00[Europe/Berlin]'), rrule: 'FREQ=WEEKLY;COUNT=10' }) // Get one event with id 123 const event = eventsServicePlugin.get(123); // Get all const events = eventsServicePlugin.getAll(); // Remove an event with id 123 eventsServicePlugin.remove(123);
Last updated on

We use cookies for marketing purposes. By clicking "Accept", you consent to the use of all cookies. If you decline, we will only use functional cookies. You can read more about our cookie policy here.