Skip to content

NthWeekdayEvent

NTH-WEEKDAY - Recurring events on the Nth weekday of a month, or the first matching weekday relative to a fixed-date anchor.

Supports two modes:

Simple mode — nth occurrence of a weekday within a calendar month:

// Mother's Day: 2nd Sunday of May
{ type: "nth-weekday", nth: 2, dayOfWeek: 0, month: 5 }
// Thanksgiving (US): 4th Thursday of November
{ type: "nth-weekday", nth: 4, dayOfWeek: 4, month: 11 }
// Last Monday of August
{ type: "nth-weekday", nth: -1, dayOfWeek: 1, month: 8 }

Anchored mode — first matching weekday on or after a fixed date, optionally bounded and with a fallback:

// Holy Family: first Sunday after Dec 25, fallback Dec 30
{ type: "nth-weekday", dayOfWeek: 0,
after: { month: 12, day: 26 }, before: { month: 12, day: 31 },
fallback: { month: 12, day: 30 } }
// Baptism of the Lord: first Sunday on/after Jan 7
{ type: "nth-weekday", dayOfWeek: 0, after: { month: 1, day: 7 } }

TMetadata extends Record<string, unknown> = Record<string, unknown>

Custom metadata type extending Record<string, unknown>

TCategory extends string = string

optional after?: DateAnchor

Find the first matching dayOfWeek on or after this date. When provided, nth and month are ignored.


optional allDay?: boolean

BaseEventProperties.allDay


optional before?: DateAnchor

Upper-bound anchor. If the first match found via after falls on or after this date, the fallback date is used instead (if supplied).


optional categories?: TCategory[]

BaseEventProperties.categories


optional color?: string

BaseEventProperties.color


dayOfWeek: 0 | 1 | 2 | 3 | 4 | 5 | 6

Day of the week (0=Sunday, 1=Monday, …, 6=Saturday)

0 // Sunday

optional description?: string

BaseEventProperties.description


optional duration?: number

BaseEventProperties.duration


optional endDate?: string

BaseEventProperties.endDate


optional endTime?: string

BaseEventProperties.endTime


optional endYear?: number

Last year the event applies (inclusive).


optional exceptions?: EventExceptions

Per-occurrence exceptions keyed by the event’s ORIGINAL computed date (YYYY-MM-DD) — maps ICS EXDATE / RECURRENCE-ID. { skip: true } drops that occurrence; { override } replaces properties for that one instance.

BaseEventProperties.exceptions


optional excludeYears?: number[]

Years to skip entirely.


optional fallback?: DateAnchor

Fallback date used when no dayOfWeek is found between after and before (inclusive). Only meaningful when before is also set.


optional icon?: string

BaseEventProperties.icon


id: string

BaseEventProperties.id


optional keywords?: string[]

BaseEventProperties.keywords


optional location?: string

BaseEventProperties.location


optional metadata?: TMetadata

BaseEventProperties.metadata


optional month?: number

Month (1-12). In simple mode, omit to repeat every month (e.g. the first Monday of every month); set it to pin one month (e.g. the 4th Thursday of November). Ignored in anchored mode.


optional nth?: 1 | 2 | 3 | 4 | -1

Which occurrence within the month:

  • 14: 1st through 4th occurrence
  • -1: last occurrence

Required in simple mode. Omit for anchored mode.


optional onConflict?: ConflictResolver

Conflict resolver for handling events on the same day. Called during event generation to determine action when this event would occur on a specific date.

Default behavior (when not specified): keep all events

BaseEventProperties.onConflict


optional overrideDates?: OverrideDatesMap

Force reschedule dates unconditionally. Unlike onConflict which handles conflicts, this always moves events. Key is the original computed date (YYYY-MM-DD), value is the new date.

overrideDates: {
"2026-02-18": "2026-02-20", // Move from Feb 18 to Feb 20
}

BaseEventProperties.overrideDates


optional priority?: number

Display precedence when several events land on the same day, like CSS z-index: higher = on top, default 0. The core only sorts by this number (highest first); it assigns no meaning to the values — the consumer does. Ties keep generation order (stable).

BaseEventProperties.priority


optional reminders?: Reminder[]

BaseEventProperties.reminders


optional source?: string

Origin of the event — the plugin, feed, or ICS subscription that produced it. Lets a consumer customize/filter in bulk by source (like toggling a calendar in Google/Apple Calendar) and namespaces the ICS export UID. Distinct from groupId (a user-defined group) and sourceEventId (the originating config id).

BaseEventProperties.source


optional startDate?: string

Recurrence validity window (YYYY-MM-DD, both bounds inclusive). Occurrences before startDate or after endDate are dropped — applied centrally during generation, so it works for ANY event type (const, monthly, weekly, nth-weekday, plugin types…), not just the few that ship their own range fields.

Maps iCalendar semantics: startDateDTSTART lower bound, endDateRRULE;UNTIL (which RFC 5545 defines as inclusive). Both are DATE values (all-day); recurrences are date-based, so no time component is involved.

// Weekly stand-up, but only for July 2026
{ type: "weekly", id: "standup", dayOfWeek: 1,
startDate: "2026-07-01", endDate: "2026-07-31" }

BaseEventProperties.startDate


optional startTime?: string

BaseEventProperties.startTime


optional startYear?: number

First year the event applies (inclusive).


optional status?: "confirmed" | "tentative" | "cancelled"

BaseEventProperties.status


optional templates?: Record<string, string>

Per-occurrence dynamic fields, derived from each occurrence’s date. A map of fieldName → template, where the template may contain date tokens ({YYYY} {MM} {DD} zero-padded · {M} {D} no padding). Each occurrence gets the field set to the interpolated value.

Applied during generation, after the base value and before a per-date exceptions[date].override (which always wins). Typically used for a date-specific url, but any string field works (title, description, location, …).

// Every Sunday's link points at a date page
{ type: "weekly", id: "mass", dayOfWeek: 0, title: "Mass",
templates: { url: "https://x.com/mass/{D}-{M}" } }
// 2026-07-07 → .../mass/7-7 · 2026-07-14 → .../mass/14-7

BaseEventProperties.templates


title: string

BaseEventProperties.title


type: "nth-weekday"


optional url?: string

BaseEventProperties.url