Bootstrap 5

Since v7.0.2

FullCalendar can take its look from your Bootstrap 5 theme. It inherits all of the theme’s style variables, including its light/dark color modes.

Useful links:

The examples below use the vanilla JS packages. The same imports work with the React, Vue, and Angular packages.

Before you begin#

You’ll need Bootstrap’s CSS as well as Bootstrap Icons, which the theme uses for its toolbar buttons, resource expander, and popover close button. Each example below pulls them in.

Activate a color mode via the data-bs-theme attribute on any parent. No other steps necessary — the calendar will pick up on it:

<html data-bs-theme="dark">

For toggling it at runtime, detecting the user-agent’s preference, and other techniques, see Bootstrap’s Color Modes documentation.

Standard Plugins#

Explore the Bootstrap 5 standard views →

ES Modules#

Install the Bootstrap 5 package, the vanilla “standard” package, and temporal-polyfill:

npm install \
  @fullcalendar/bootstrap5 \
  fullcalendar \
  temporal-polyfill \
  bootstrap \
  bootstrap-icons

Then, supply the theme as a plugin:

import { Calendar } from 'fullcalendar'
import bootstrapPlugin from '@fullcalendar/bootstrap5'
import dayGridPlugin from 'fullcalendar/daygrid'
import timeGridPlugin from 'fullcalendar/timegrid'

import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-icons/font/bootstrap-icons.css'
import 'fullcalendar/skeleton.css'
import '@fullcalendar/bootstrap5/theme.css'

const calendar = new Calendar(calendarEl, {
  plugins: [bootstrapPlugin, dayGridPlugin, timeGridPlugin],
  initialView: 'dayGridMonth',
  headerToolbar: {
    left: 'prevYear,prev,next,nextYear today',
    center: 'title',
    right: 'dayGridMonth,timeGridWeek',
  },
  // your other options here
})

calendar.render()

Script Tags#

The theme’s global.js registers itself, so no plugins array is necessary (more info):

<!DOCTYPE html>
<html lang="en" data-bs-theme="light">
  <head>
    <meta charset="utf-8" />

    <!-- STANDARD JS -->
    <script src="https://cdn.jsdelivr.net/npm/fullcalendar@7.1.1/all/global.js"></script>

    <!-- THEME JS -->
    <script src="https://cdn.jsdelivr.net/npm/@fullcalendar/bootstrap5@7.1.1/global.js"></script>

    <!-- STYLESHEETS -->
    <link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css' rel='stylesheet' />
    <link href='https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.min.css' rel='stylesheet' />
    <link href='https://cdn.jsdelivr.net/npm/fullcalendar@7.1.1/skeleton.css' rel='stylesheet' />
    <link href='https://cdn.jsdelivr.net/npm/@fullcalendar/bootstrap5@7.1.1/theme.css' rel='stylesheet' />

    <script>
      document.addEventListener("DOMContentLoaded", function () {
        const calendarEl = document.getElementById("calendar");
        const calendar = new FullCalendar.Calendar(calendarEl, {
          initialView: "dayGridMonth",
          headerToolbar: {
            left: "prevYear,prev,next,nextYear today",
            center: "title",
            right: "dayGridMonth,timeGridWeek",
          },
        });
        calendar.render();
      });
    </script>
  </head>
  <body>
    <div id="calendar"></div>
  </body>
</html>

Premium Plugins#

Explore the Bootstrap 5 timeline view or vertical resource view.

ES Modules#

Install the Bootstrap 5 package, the vanilla “scheduler” package, the vanilla “standard” package, and temporal-polyfill:

npm install @fullcalendar/bootstrap5 \
  fullcalendar-scheduler \
  fullcalendar \
  temporal-polyfill \
  bootstrap \
  bootstrap-icons

The theme covers the premium views as well:

import { Calendar } from 'fullcalendar'
import bootstrapPlugin from '@fullcalendar/bootstrap5'
import resourceTimelinePlugin from 'fullcalendar-scheduler/resource-timeline'
import resourceTimeGridPlugin from 'fullcalendar-scheduler/resource-timegrid'

import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-icons/font/bootstrap-icons.css'
import 'fullcalendar/skeleton.css'
import '@fullcalendar/bootstrap5/theme.css'

const calendar = new Calendar(calendarEl, {
  plugins: [bootstrapPlugin, resourceTimelinePlugin, resourceTimeGridPlugin],
  initialView: 'resourceTimelineWeek',
  headerToolbar: {
    left: 'prevYear,prev,next,nextYear today',
    center: 'title',
    right: 'resourceTimelineWeek,resourceTimeGridDay',
  },
  // your other options here
})

calendar.render()

Script Tags#

Include the scheduler bundle alongside the standard one, then the theme:

<!DOCTYPE html>
<html lang="en" data-bs-theme="light">
  <head>
    <meta charset="utf-8" />

    <!-- STANDARD + SCHEDULER JS -->
    <script src="https://cdn.jsdelivr.net/npm/fullcalendar@7.1.1/all/global.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/fullcalendar-scheduler@7.1.1/all/global.js"></script>

    <!-- THEME JS -->
    <script src="https://cdn.jsdelivr.net/npm/@fullcalendar/bootstrap5@7.1.1/global.js"></script>

    <!-- STYLESHEETS -->
    <link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css' rel='stylesheet' />
    <link href='https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.1/font/bootstrap-icons.min.css' rel='stylesheet' />
    <link href='https://cdn.jsdelivr.net/npm/fullcalendar@7.1.1/skeleton.css' rel='stylesheet' />
    <link href='https://cdn.jsdelivr.net/npm/@fullcalendar/bootstrap5@7.1.1/theme.css' rel='stylesheet' />

    <script>
      document.addEventListener("DOMContentLoaded", function () {
        const calendarEl = document.getElementById("calendar");
        const calendar = new FullCalendar.Calendar(calendarEl, {
          initialView: "resourceTimelineWeek",
          headerToolbar: {
            left: "prevYear,prev,next,nextYear today",
            center: "title",
            right: "resourceTimelineWeek,resourceTimeGridDay",
          },
        });
        calendar.render();
      });
    </script>
  </head>
  <body>
    <div id="calendar"></div>
  </body>
</html>