# Templates and Recurrence
URL: https://pro.rv-grid.com/guides/event-scheduler/templates-recurrence/
Source: src/content/docs/guides/event-scheduler/templates-recurrence.mdx
Description: Create scheduler events from reusable templates and generate repeating shifts or bookings.
Templates define reusable event shapes. The plugin exposes helper methods for single events and recurring series.

```ts
grid.eventSchedulerTemplates = [
  {
    id: 'morning-shift',
    title: 'Morning shift',
    durationMinutes: 480,
    status: 'planned',
    type: 'shift',
    color: '#2563eb',
  },
];

const scheduler = (await grid.getPlugins()).find(
  (plugin) => plugin.constructor?.name === 'EventSchedulerPlugin',
);

scheduler.createRecurringEvents({
  templateId: 'morning-shift',
  resourceId: 'emp-alex',
  startDateTime: '2026-06-08T08:00:00.000Z',
  recurrence: {
    frequency: 'weekly',
    weekdays: [1, 3, 5],
    count: 6,
  },
  seriesId: 'alex-morning-series',
});
```

Generated events keep recurrence metadata so applications can present edit-series or delete-series workflows.

## Copy, Paste, Duplicate, and Bulk Helpers

Get the plugin instance to run imperative scheduler helpers:

```ts
const plugins = await grid.getPlugins();
const scheduler = plugins.find(
  (plugin) => plugin.constructor?.name === 'EventSchedulerPlugin',
);
```

Create one event from a template:

```ts
scheduler?.createEventFromTemplate({
  templateId: 'morning-shift',
  startDateTime: '2026-06-08T08:00:00.000Z',
  resourceId: 'team-a',
});
```

Copy a day or pattern into another date range:

```ts
scheduler?.duplicateScheduleRange({
  sourceStartDateTime: '2026-06-08T00:00:00.000Z',
  sourceEndDateTime: '2026-06-09T00:00:00.000Z',
  targetStartDateTime: '2026-06-09T00:00:00.000Z',
});
```

Selection helpers support copy, paste, duplicate, bulk delete, and bulk status changes:

```ts
scheduler?.setSelectedEventIds(['shift-a', 'shift-b']);
scheduler?.copySelectedEvents();
scheduler?.pasteCopiedEvents({ startDateTime: '2026-06-10T08:00:00.000Z' });
scheduler?.bulkUpdateSelectedEventStatus('confirmed');
```

All helper actions run through the same permissions, conflict, before-change, local mutation, event emission, and remote mutation pipeline as pointer and editor interactions.
