Angular Component
FullCalendar seamlessly integrates with Angular 16 - 22. It provides a component that exactly matches the functionality of FullCalendar’s standard API.
This component is built and maintained by irustm in partnership with the maintainers of FullCalendar. It is the official Angular connector, 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: Angular 22 | 21 | 20 | 19 | 18 | 17 | 16
Installation#
This guide does not go into depth about initializing an Angular project. Please consult the aforementioned example/runnable projects for that.
The first step is to install the FullCalendar-related dependencies. You’ll need FullCalendar core, the Angular adapter, and any plugins you plan to use:
npm install --save @fullcalendar/angular fullcalendar temporal-polyfill Some notes:
- The
temporal-polyfillpackage is small and tree-shakable, and can be used as a global polyfill if you explicitly opt-in (more info). - The
fullcalendarpackage will never be imported directly when using Angular. Always use@fullcalendar/angular.
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.
In one of your app’s component files (app.component.ts), prepare an object of options along with any plugins:
import { Component } from "@angular/core";
import { CommonModule } from "@angular/common";
import { RouterOutlet } from "@angular/router";
import { FullCalendarModule, CalendarOptions } from "@fullcalendar/angular";
import themePlugin from "@fullcalendar/angular/themes/monarch"; // YOUR THEME
import dayGridPlugin from "@fullcalendar/angular/daygrid";
@Component({
selector: "app-root",
standalone: true,
imports: [CommonModule, RouterOutlet, FullCalendarModule],
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
})
export class AppComponent {
calendarOptions: CalendarOptions = {
initialView: "dayGridMonth",
plugins: [themePlugin, dayGridPlugin],
};
} Then, add the following stylesheets to your angular.json:
{
"projects": { // ...
"my-project": { // ...
"architect": { // ...
"build": { // ...
"options": { // ...
"styles": [
+ "@fullcalendar/angular/skeleton.css", // ALWAYS NEED SKELETON
+ "@fullcalendar/angular/themes/monarch/theme.css", // YOUR THEME
+ "@fullcalendar/angular/themes/monarch/palettes/purple.css", // YOUR THEME'S PALETTE
"src/styles.css"
] Then, in your component’s template file (app.component.html), you have access to the <full-calendar> tag. You must pass your options into this declaration!
<full-calendar [options]="calendarOptions"></full-calendar> Options#
The <full-calendar> component accepts all of FullCalendar’s options through a single options input. They are written as key-value pairs in one object, rather than as individual inputs. Example:
calendarOptions: 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#
Angular has the concept of bound input data (written with [brackets]) versus outputs (written with (parentheses)). For the FullCalendar connector, there is no distinction between inputs and outputs. 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:
import { Component } from "@angular/core";
import { CalendarOptions } from "@fullcalendar/angular";
// ...
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
})
export class AppComponent {
calendarOptions: CalendarOptions = {
initialView: "dayGridMonth",
plugins: [ /* ... */ ],
dateClick: (info) => this.handleDateClick(info),
events: [
{ title: "event 1", date: "2026-04-01" },
{ title: "event 2", date: "2026-04-02" },
],
};
handleDateClick(info) {
alert("date click! " + info.dateStr);
}
} Template:
<full-calendar [options]="calendarOptions"></full-calendar> Inputs for events/eventSources/resources
Certain options are exposed as top-level component inputs for convenience. This works well with the async template helper, which accepts an Observable or Promise. The above example rewritten:
import { Component } from "@angular/core";
import { CalendarOptions, EventInput } from "@fullcalendar/angular";
// ...
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
})
export class AppComponent {
calendarOptions: CalendarOptions = {
initialView: "dayGridMonth",
plugins: [ /* ... */ ],
dateClick: (info) => this.handleDateClick(info),
};
eventsPromise: Promise<EventInput[]>;
handleDateClick(info) {
alert("date click! " + info.dateStr);
}
} Template:
<full-calendar
[options]="calendarOptions"
[events]="eventsPromise | async"
></full-calendar> This technique is commonly used when working with NgRx.
Modifying Options#
You can modify FullCalendar’s options dynamically by reassigning them within the options object. This example toggles the weekends option on and off:
import { Component } from "@angular/core";
import { CalendarOptions } from "@fullcalendar/angular";
// ...
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
})
export class AppComponent {
calendarOptions: CalendarOptions = {
initialView: "dayGridMonth",
plugins: [ /* ... */ ],
weekends: false, // initial value
};
toggleWeekends() {
this.calendarOptions.weekends = !this.calendarOptions.weekends; // toggle the boolean!
}
} and the template:
<button (click)="toggleWeekends()">toggle weekends</button>
<full-calendar [options]="calendarOptions"></full-calendar> If you want to modify options that are complex objects, like headerToolbar or events, you’ll need to make a copy of the object, make your change, and then reassign it. If you DO NOT want to do this, you can have the angular connector recursively search for changes within your objects, though this comes at a slight performance cost. Set the deepChangeDetection prop to "true":
<full-calendar
[options]="calendarOptions"
deepChangeDetection="true"
></full-calendar> Content Injection#
There are many settings throughout the API for injecting custom content, like the eventContent event render hook. When you’re using the Angular connector, these are written as nested ng-template tags, named after the setting:
<full-calendar [options]="calendarOptions">
<ng-template #eventContent let-info>
<b>{{ info.event.title }}</b>
</ng-template>
</full-calendar> Explanation:
- The template is named via the
#syntax. It must be the name of a content-injection setting. - The template accepts a single implicit local variable which is named via the
let-*syntax. In the above example,let-infonames the variable “info”. - The properties of the argument are documented alongside each setting. For example see eventContent’s argument.
For more complex situations, a TemplateRef can be directly passed to the options. This is useful for nested options like resourceColumns’ .cellContent.
Custom Toolbar Markup#
The CalendarController technique for writing your own toolbar markup is not yet available for Angular. Arrange the built-in toolbar with headerToolbar and footerToolbar, and define your own buttons with buttons. For anything beyond that, write your own markup and call the date navigation methods through the Calendar 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 ViewChild reference. In the template:
<full-calendar #calendar [options]="calendarOptions"></full-calendar> Once you’ve explicitly marked your child component (#calendar), you can get the underlying Calendar object via the getApi method:
import { Component, ViewChild } from "@angular/core";
import { FullCalendarComponent, CalendarOptions } from "@fullcalendar/angular";
// ...
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
})
export class AppComponent {
// references the #calendar in the template
@ViewChild("calendar") calendarComponent: FullCalendarComponent;
calendarOptions: CalendarOptions = {
initialView: "dayGridMonth",
plugins: [ /* ... */ ],
};
someMethod() {
const calendarApi = this.calendarComponent.getApi();
calendarApi.next();
}
} FullCalendar Premium#
How do you use FullCalendar Premium’s plugins with Angular? 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/angular-scheduler Then, initialize your calendar. Make sure to include your schedulerLicenseKey:
import { Component } from "@angular/core";
import { CalendarOptions } from "@fullcalendar/angular";
import themePlugin from "@fullcalendar/angular/themes/monarch";
import resourceTimelinePlugin from "@fullcalendar/angular-scheduler/resource-timeline";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
})
export class AppComponent {
calendarOptions: CalendarOptions = {
schedulerLicenseKey: "XXX",
plugins: [themePlugin, resourceTimelinePlugin],
};
} TypeScript#
For @fullcalendar/angular, nothing special is needed for TypeScript integration. Types are already included. The CalendarOptions type used throughout this guide is one of them.