Salesforce Lightning Web Component (LWC)
FullCalendar can run inside a Salesforce Lightning Web Component, letting you embed a calendar directly in a Lightning page, an App Builder component, or a Salesforce Experience Cloud site.
Rather than an NPM package, this integration is distributed as a zip of Salesforce metadata that you deploy to your org. It packages FullCalendar’s global build as a static resource and wraps it in a c-full-calendar Lightning Web Component. FullCalendar renders its button icons as inline SVG rather than icon fonts, which avoids the font-loading and Content Security Policy restrictions that Salesforce’s Lightning platform enforces on third-party resources.
Useful links:
This integration is newer than FullCalendar’s other framework packages and feedback on the distribution approach is very welcome — please comment on the tracking issue.
Installation#
Download the zip from the GitHub release. The file name carries the version number, so it changes with every release:
- Download: fullcalendar-lwc-7.1.0.zip
For premium, see FullCalendar Premium below. To grab a different version, find it on the releases page and download its fullcalendar-lwc-*.zip asset. LWC support was added in v7.0.1.
Then:
- Unpack the zip.
- Copy
force-app/main/default/into the corresponding package directory of your SFDX project. - Deploy it:
sf project deploy start The zip contains two components: fullCalendar, the low-level programmatic wrapper described in this article, and fullCalendarDemo, a ready-made Lightning App Builder component you can drop onto a page.
Basic Usage#
In your own component’s template, render the c-full-calendar tag and give it an options object:
<template>
<c-full-calendar options={calendarOptions}></c-full-calendar>
</template> import { LightningElement } from 'lwc'
export default class MyCalendar extends LightningElement {
calendarOptions = {
initialView: 'dayGridMonth',
events: [
{ title: 'event 1', date: '2026-04-01' },
{ title: 'event 2', date: '2026-04-02' },
],
}
} Unlike the React and Vue packages, you do not pass a plugins array. The static resource is FullCalendar’s global build, so all standard plugins and views are already registered.
Options#
The options property accepts all of FullCalendar’s options as plain key-value pairs, exactly as you would pass them to the Calendar constructor.
Three settings are instead supplied as their own attributes on the tag, because the component must load assets for them: theme, theme-palette, and locale.
<c-full-calendar
options={calendarOptions}
theme="forma"
theme-palette="blue"
locale="en-gb"
></c-full-calendar> locale in particular must be set through the attribute rather than through options — the component loads the matching locale asset asynchronously before applying it. See the localization article for what a locale affects.
Options can also be scoped to a single view, or to a type of view, through the views option. See View-Specific Options.
Themes and Palettes#
theme is one of the five stock themes. theme-palette is optional; each theme falls back to its own default (shown in bold). See the color palettes article for what a palette controls.
classic— a single built-in palette (theme-paletteis ignored)breezy— amber, emerald, indigo, roseforma— blue, green, purple, redmonarch— blue, green, purple, red, yellowpulse— blue, green, purple, red
Handlers#
Handler functions placed in options are called normally:
calendarOptions = {
dateClick: (info) => {
console.log(info.dateStr)
},
} In addition, the component re-dispatches FullCalendar’s listeners as LWC custom events. LWC requires event names to be lowercase, so eventClick becomes oneventclick:
<c-full-calendar
options={calendarOptions}
oneventclick={handleEventClick}
></c-full-calendar> handleEventClick(event) {
console.log(event.detail)
} The argument FullCalendar would normally pass to the handler arrives on event.detail. Both mechanisms work at once — a re-dispatched event does not replace the function in options.
Modifying Options#
To change options after initialization, reassign the options object. The wrapper only reacts when the options object is reassigned. Mutating the existing object in place will not trigger an update. Spread it into a new object instead:
toggleWeekends() {
this.calendarOptions = {
...this.calendarOptions,
weekends: !this.calendarOptions.weekends,
}
} Content Injection#
There are many settings throughout the API for injecting custom content, like the eventContent event render hook. Lightning Web Component templates can’t be passed into the calendar, so these settings accept the same formats as vanilla JS: a string, HTML, DOM nodes, or a function returning any of those. See the vanilla JS instructions.
Calendar API#
To access the underlying Calendar object for raw data and methods — most commonly for date navigation — call getCalendar() on the component instance:
const calendar = this.template.querySelector('c-full-calendar').getCalendar()
calendar.next() Additional Plugins#
Any FullCalendar plugin that ships a global build can be loaded by giving the component an array of static-resource URLs through plugin-urls. The component loads each script and registers its plugins during initialization. This is how the premium Scheduler runtime is added.
Lightning App Builder Demo#
The fullCalendar component is intended for programmatic composition and deliberately does not appear in Lightning App Builder. The zip also ships a FullCalendar Demo component that does, with representative toolbar, event, interaction, theme, palette, and locale configuration.
To try it after deploying:
- In the deployed org, open Setup from the gear menu.
- Use Quick Find to open Lightning App Builder, then click New.
- Select App Page, enter a label such as FullCalendar Demo, select the standard One Region template, and click Done.
- Under Custom, drag FullCalendar Demo onto the page and choose its Theme and Locale.
- Click Save and Activate, create the Lightning tab if prompted, and add the page to a Lightning app such as Sales.
- Open that app from the App Launcher and verify the calendar and its sample events.
Its source, fullCalendarDemo, is a good reference for writing an application-specific wrapper that supplies its own options, data, and handlers.
FullCalendar Premium#
FullCalendar Premium’s plugins come as a separate zip:
- Download: fullcalendar-scheduler-lwc-7.1.0.zip
Other versions are on the premium releases page. Install it the same way as the standard zip.
This zip is self-sufficient — it contains everything the standard zip does, so you don’t install both. It deploys an identical c-full-calendar component and additionally ships the Scheduler runtime as the fullCalendarSchedulerLib static resource, so upgrading from the standard package requires no markup changes. (Deploying both does work, but only so the two can be demoed side by side.)
Point plugin-urls at the Scheduler runtime, and supply resources, a resource view, and your schedulerLicenseKey through options:
<c-full-calendar
options={calendarOptions}
theme="monarch"
plugin-urls={pluginUrls}
onresourceadd={handleResourceAdd}
></c-full-calendar> import fullCalendarSchedulerLib from '@salesforce/resourceUrl/fullCalendarSchedulerLib'
pluginUrls = [`${fullCalendarSchedulerLib}/all/global.js`]
calendarOptions = {
initialView: 'resourceTimelineWeek',
schedulerLicenseKey: 'XXX',
resources: [
{ id: 'a', title: 'Room A' },
{ id: 'b', title: 'Room B' },
],
events: [{ title: 'Meeting', start: '2026-07-15T10:00:00', resourceId: 'a' }],
} Set options.initialView to a resource view yourself. Without it, the calendar renders the standard dayGridMonth default.
With the Scheduler runtime loaded, the component also re-dispatches the resource listeners — resourcesSet, resourceAdd, resourceChange and resourceRemove — as onresourcesset, onresourceadd, onresourcechange and onresourceremove.
The premium zip has its own Lightning App Builder demo, FullCalendar Scheduler Demo (source: fullCalendarSchedulerDemo), which follows the same steps as above but with resource timeline configuration.
Known Limitations#
theme-paletteandplugin-urlsare read once, during initial render. Recreate the component to change them.thememay be changed at any time; the new theme’s assets load asynchronously before being applied.- Two calendars on the same page must not use the same theme with different palettes. Palette CSS variables are page-global per theme.
- The component relies on Salesforce static-resource loading, and on Lightning Web Security allowing FullCalendar’s IIFE bundle to attach to its
windowglobal.