Introduction
A booking calendar is the heart of any scheduling or appointment system. Users expect to see availability in real-time, interact with slots, and make bookings without refreshing the page.
By combining FullCalendar.js, a powerful JavaScript library for interactive calendars, with the WordPress REST API, we can create a fully dynamic booking calendar that integrates seamlessly into WordPress.
This guide walks you through the architecture, implementation, and customization of a scalable booking calendar system.
Why Use FullCalendar with WordPress?
FullCalendar.js provides:
- Drag-and-drop support for events.
- Day, week, and month views.
- Recurring events and resources.
- AJAX-powered updates.
- Timezone and localization support.
When paired with the WordPress REST API, you can:
- Fetch bookings in real time.
- Display service/staff availability dynamically.
- Allow users to create, update, or cancel bookings without reloading.
Step 1: Setting Up a Booking Post Type
First, register a Booking Custom Post Type (CPT) in WordPress:
function register_booking_post_type() {
register_post_type('bookings', [
'labels' => [
'name' => __('Bookings', 'bookwp'),
'singular_name' => __('Booking', 'bookwp'),
],
'public' => false,
'show_ui' => true,
'supports' => ['title'],
'menu_icon' => 'dashicons-calendar-alt',
]);
}
add_action('init', 'register_booking_post_type');
Each booking will store:
- Service
- Staff
- Start time
- End time
- Status
Step 2: Exposing Bookings via WP REST API
Use WordPress’s REST API to serve booking data:
function register_booking_rest_routes() {
register_rest_route('bookwp/v1', '/bookings', [
'methods' => 'GET',
'callback' => 'get_bookings',
]);
}
add_action('rest_api_init', 'register_booking_rest_routes');
function get_bookings() {
$args = [
'post_type' => 'bookings',
'post_status' => 'publish',
'numberposts' => -1,
];
$bookings = get_posts($args);
$events = [];
foreach ($bookings as $booking) {
$events[] = [
'id' => $booking->ID,
'title' => get_the_title($booking),
'start' => get_post_meta($booking->ID, 'start_time', true),
'end' => get_post_meta($booking->ID, 'end_time', true),
];
}
return $events;
}
This endpoint (/wp-json/bookwp/v1/bookings
) provides events for FullCalendar.
Step 3: Adding FullCalendar.js to WordPress
Enqueue the FullCalendar scripts and styles:
function enqueue_fullcalendar_assets() {
wp_enqueue_script('fullcalendar', 'https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.js', [], null, true);
wp_enqueue_style('fullcalendar-style', 'https://cdn.jsdelivr.net/npm/fullcalendar@6.1.8/index.global.min.css');
wp_enqueue_script('booking-calendar', plugin_dir_url(__FILE__) . 'assets/js/booking-calendar.js', ['fullcalendar'], null, true);
wp_localize_script('booking-calendar', 'bookwpData', [
'restUrl' => esc_url(rest_url('bookwp/v1/bookings')),
]);
}
add_action('wp_enqueue_scripts', 'enqueue_fullcalendar_assets');
Step 4: Rendering the Calendar in JavaScript
In booking-calendar.js
:
document.addEventListener('DOMContentLoaded', function() {
const calendarEl = document.getElementById('booking-calendar');
const calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'timeGridWeek',
events: bookwpData.restUrl, // Fetch from WP REST API
selectable: true,
editable: true,
eventClick: function(info) {
alert('Booking: ' + info.event.title);
},
select: function(info) {
alert('Selected time: ' + info.startStr + ' to ' + info.endStr);
}
});
calendar.render();
});
Add a shortcode to render the calendar container:
function booking_calendar_shortcode() {
return '<div id="booking-calendar"></div>';
}
add_shortcode('booking_calendar', 'booking_calendar_shortcode');
Step 5: Adding Booking Creation & Updates
To allow users to create bookings:
- Use the
select
callback in FullCalendar. - Call a custom REST endpoint (
POST /bookings
) to save the booking. - Update the calendar dynamically with
calendar.addEvent()
.
Example select
handler:
select: function(info) {
fetch(bookwpData.restUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title: 'New Booking',
start: info.startStr,
end: info.endStr,
})
})
.then(res => res.json())
.then(data => {
calendar.addEvent(data); // Render new event
});
}
Step 6: Customization & Advanced Features
Enhance your calendar with:
- Color coding by service or staff.
- Recurring availability patterns.
- Drag-and-drop rescheduling (using
eventDrop
). - External system integration (Google Calendar, Outlook).
- Timezone handling for global businesses.
Conclusion
By integrating FullCalendar.js with the WordPress REST API, you can create a powerful, real-time booking calendar that’s interactive, scalable, and user-friendly.