Appointments let visitors book a time with you: a consultation, a fitting, a viewing. You say when you are free, a visitor picks a time and answers your questions, and you accept the booking or it is accepted at once. You and the visitor each get an email with a calendar invite. By the end of this chapter you will have a calendar that people can book from a page.
Appointments are a feature: a package you add to the site and list in site.config.ts. A site that was created with appointments chosen already has this, so go straight to “Make a calendar”.
pnpm add @jamiemcconnell/cms-appointmentssite.config.ts, import appointments and list it under features:import { defineConfig } from '@jamiemcconnell/cms';
import { appointments } from '@jamiemcconnell/cms-appointments';
export default defineConfig({
// …the rest of your settings stay as they are…
features: [appointments()],
});pnpm dev with Ctrl+C and run it again. No migration is needed. Appointments now appears in the admin's sidebar.A calendar is one bookable thing with one owner, such as “Consultation” or “Fitting”. Admins make calendars; any editor can work on the bookings and the availability of one.
Weekly hours are the day-by-day time ranges when you can be booked, in the calendar's time zone. Below them, a week view lets you drag over a stretch of time for a change on one date. Its “This time is” choice says which kind: Open (an extra opening), such as a Saturday morning, or Blocked (time off), such as a holiday or a lunch break.
Name, email and message are always asked. Under Questions, only admins can add anything else you want to know before the appointment: a line of text, a choice, a date and so on. Files and images are not available.
A calendar with upcoming bookings cannot be deleted.
The block shows a month of days with the free ones marked, then the times of the chosen day in the visitor's own time zone (naming the calendar's zone when it differs), then the form. The words, from the heading and buttons to the thank-you for each outcome and the error messages, are fields of the block.
The block needs script, and runs a CSRF token and a proof-of-work check against bots, as forms do. If two visitors choose the same time, one gets the booking. The other is told that the time has been taken and sees fresh times.
With “Accept bookings automatically” on, a booking is confirmed on the spot. Without it, the booking is pending and holds its time until you decide: Accept confirms it, and Decline releases the time. Pending bookings are on the calendar's Bookings tab, on the dashboard, and each opens on a page of its own with the visitor's answers.
A booking still pending when its start time passes is marked expired, and the visitor is told. You can cancel any live booking, and so can the visitor.
Seven emails cover the steps:
The confirmed and cancelled emails carry a calendar invite, so the appointment goes into both calendars without anyone copying it. A cancellation updates the same entry, so it disappears and does not leave a second one. Invites come from the site's From address, set under Settings → Email, and nobody is asked to reply.
The wording of each email is under Content → Emails. They are only sent once the site has a real email provider (Going live). The SMTP and SES providers send the invite inline. A provider that cannot do that still sends the email, and the link in it downloads the same file.
Every email to the visitor has a link to a private page where they see their booking, add it to a calendar and cancel it. That page is a callback page called “Your appointment”. The site makes it the first time it is needed, and you edit it like any other under Content → Callback pages.