Vue Component
FullCalendar seamlessly integrates with Vue 3. It provides a component that exactly matches the functionality of FullCalendar’s standard API.
This package is released under an MIT license, the same license the standard version of FullCalendar uses. Useful links:
- Browse the Github repo (please star it!)
- NPM package
- Bug report instructions
- Example projects:
- Standard: StackBlitz | Github Source
- Scheduler: StackBlitz | Github Source
Installation#
This guide does not go into depth about initializing a Vue project. Please consult the aforementioned example/runnable projects for that.
The first step is to install the FullCalendar-related dependencies:
npm install --save @fullcalendar/vue3 temporal-polyfill The temporal-polyfill package is small and tree-shakable, and can be used as a global polyfill if you explicitly opt-in (more info).
Next, choose one of the stock themes (see them live), along with a color palette. The examples below show a simplified way of importing the color palette (ex: purple.css), but please be aware, there are better ways to integrate with dark mode.
You may then begin to write a parent component that leverages the <FullCalendar> component:
<script setup>
import FullCalendar from "@fullcalendar/vue3";
import themePlugin from "@fullcalendar/vue3/themes/monarch"; // YOUR THEME
import dayGridPlugin from "@fullcalendar/vue3/daygrid";
import interactionPlugin from "@fullcalendar/vue3/interaction";
// stylesheets
import '@fullcalendar/vue3/skeleton.css'; // ALWAYS NEED SKELETON
import '@fullcalendar/vue3/themes/monarch/theme.css'; // YOUR THEME
import '@fullcalendar/vue3/themes/monarch/palettes/purple.css'; // YOUR THEME'S PALETTE
const calendarOptions = {
plugins: [themePlugin, dayGridPlugin, interactionPlugin],
initialView: "dayGridMonth",
};
</script>
<template>
<FullCalendar :options="calendarOptions" />
</template> These examples use the Composition API with <script setup>, where an imported component like FullCalendar is automatically available to the template. If you use the Options API instead, register it via components: { FullCalendar } and expose the options object from data().
Options#
The <FullCalendar> component accepts all of FullCalendar’s options through a single options prop. They are written as key-value pairs in one object, rather than as individual props. Example:
const calendarOptions = {
plugins: [ /* ... */ ],
initialView: "dayGridMonth",
weekends: false,
events: [
{ title: "event 1", date: "2026-04-01" },
{ title: "event 2", date: "2026-04-02" },
],
}; Options can also be scoped to a single view, or to a type of view, through the views option. See View-Specific Options.
Handlers#
Vue has the concept of “props” (via v-bind or :) versus “events” (via v-on or @). For the FullCalendar connector, there is no distinction between props and events. Handlers are passed into the same options object as everything else. Here is an example that demonstrates passing in an events array and a dateClick handler:
<script setup>
import FullCalendar from "@fullcalendar/vue3";
// ...
function handleDateClick(info) {
alert("date click! " + info.dateStr);
}
const calendarOptions = {
plugins: [ /* ... */ ],
initialView: "dayGridMonth",
dateClick: handleDateClick,
events: [
{ title: "event 1", date: "2026-04-01" },
{ title: "event 2", date: "2026-04-02" },
],
};
</script>
<template>
<FullCalendar :options="calendarOptions" />
</template> Modifying Options#
You can modify your calendar’s options after initialization by reassigning them within the options object. Make the object reactive so the calendar picks up the change. This is an example of changing the weekends option:
<script setup>
import { reactive } from "vue";
import FullCalendar from "@fullcalendar/vue3";
// ...
const calendarOptions = reactive({
plugins: [ /* ... */ ],
initialView: "dayGridMonth",
weekends: false, // initial value
});
function toggleWeekends() {
calendarOptions.weekends = !calendarOptions.weekends; // toggle the boolean!
}
</script>
<template>
<button @click="toggleWeekends">toggle weekends</button>
<FullCalendar :options="calendarOptions" />
</template> Content Injection#
There are many settings throughout the API for injecting custom content, like the eventContent event render hook. When you’re using the Vue connector, these are written as slot templates, named after the setting:
<template>
<FullCalendar :options="calendarOptions">
<template v-slot:eventContent="info">
<b>{{ info.event.title }}</b>
</template>
</FullCalendar>
</template> All slots are scoped slots that accept an argument (explicitly named info in the above example). Its properties are documented alongside each setting. For example, see eventContent’s argument.
Custom Toolbar Markup#
You can completely customize the markup for the header or footer toolbars:
<script setup>
import FullCalendar, { useCalendarController } from "@fullcalendar/vue3";
// ...
const controller = useCalendarController()
const buttons = controller.getButtonState()
const calendarOptions = {
controller, // give to calendar options
plugins: [ /* ... */ ],
initialView: "dayGridMonth",
};
</script>
<template>
<div class='toolbar'>
<button @click="controller.today()">{{ buttons.today.text }}</button>
<div class='toolbar-title'>{{ controller.view.title }}</div>
</div>
<FullCalendar :options="calendarOptions" />
</template> More generally, this “controller” technique allows you to use a calendar’s data outside the component itself. Learn about the CalendarController API →
Calendar API#
Hopefully you won’t need to do it often, but sometimes it’s useful to access the underlying Calendar object for raw data and methods.
This is especially useful for controlling the current date. The initialDate prop will set the initial date of the calendar, but to change it after that, you’ll need to rely on the date navigation methods.
To do something like this, you’ll need to get ahold of the component’s template ref (short for “reference”). Declare a ref with the same name as the ref attribute in the template:
<script setup>
import { ref } from "vue";
import FullCalendar from "@fullcalendar/vue3";
// ...
const fullCalendar = ref(null);
</script>
<template>
<FullCalendar ref="fullCalendar" :options="calendarOptions" />
</template> Once you have the ref, you can get the underlying Calendar object via the getApi method:
const calendarApi = fullCalendar.value.getApi();
calendarApi.next(); FullCalendar Premium#
How do you use FullCalendar Premium’s plugins with Vue? They are no different than any other plugin. Just follow the same instructions as you did dayGridPlugin in the above example. You’ll need an additional package however:
npm install --save @fullcalendar/vue3-scheduler Then, initialize your calendar. Make sure to include your schedulerLicenseKey:
<script setup>
import FullCalendar from "@fullcalendar/vue3";
import themePlugin from "@fullcalendar/vue3/themes/monarch";
import resourceTimelinePlugin from "@fullcalendar/vue3-scheduler/resource-timeline";
// stylesheets
import '@fullcalendar/vue3/skeleton.css';
import '@fullcalendar/vue3/themes/monarch/theme.css';
import '@fullcalendar/vue3/themes/monarch/palettes/purple.css';
const calendarOptions = {
plugins: [themePlugin, resourceTimelinePlugin],
schedulerLicenseKey: "XXX",
};
</script>
<template>
<FullCalendar :options="calendarOptions" />
</template> TypeScript#
For @fullcalendar/vue3, nothing special is needed for TypeScript integration. Types are already included.
Kebab-case in Markup#
Some people prefer to write component names in kebab-case when writing markup. This will work fine:
<full-calendar :options="calendarOptions" /> However, the properties within calendarOptions must have the same names.
Nuxt#
If you plan to use the Nuxt Vue framework, you’ll need special configuration. See the example project